1<!DOCTYPE html> 2<html 3 lang="ja" 4 5 6data-admin-domain="//blog.hatena.ne.jp" 7data-admin-origin="https://blog.hatena.ne.jp" 8data-author="atr0phy" 9data-avail-langs="ja en" 10data-blog="atr0phy.hateblo.jp" 11data-blog-host="atr0phy.hateblo.jp" 12data-blog-is-public="1" 13data-blog-name="HackToTech" 14data-blog-owner="atr0phy" 15data-blog-show-ads="" 16data-blog-show-sleeping-ads="" 17data-blog-uri="https://www.hacktotech.net/" 18data-blog-uuid="26006613489834982" 19data-blogs-uri-base="https://www.hacktotech.net" 20data-brand="pro" 21data-data-layer="{"hatenablog":{"admin":{},"analytics":{"brand_property_id":"","measurement_id":"G-N5T771Z5Q2","non_sampling_property_id":"","property_id":"","separated_property_id":"UA-29716941-18"},"blog":{"blog_id":"26006613489834982","content_seems_japanese":"true","disable_ads":"custom_domain","enable_ads":"false","entry_show_footer_related_entries":"true","force_pc_view":"true","is_public":"true","is_responsive_view":"true","is_sleeping":"false","lang":"ja","name":"HackToTech","owner_name":"atr0phy","uri":"https://www.hacktotech.net/"},"brand":"pro","page_id":"index","permalink_entry":null,"pro":"pro","router_type":"blogs"}}" 22data-device="pc" 23data-dont-recommend-pro="false" 24data-global-domain="https://hatena.blog" 25data-globalheader-color="b" 26data-globalheader-type="pc" 27data-has-touch-view="1" 28data-help-url="https://help.hatenablog.com" 29data-hide-header="1" 30data-no-suggest-touch-view="1" 31data-page="index" 32data-parts-domain="https://hatenablog-parts.com" 33data-plus-available="1" 34data-pro="true" 35data-router-type="blogs" 36data-sentry-dsn="https://[email protected]/1195218" 37data-sentry-environment="production" 38data-sentry-sample-rate="0.1" 39data-static-domain="https://cdn.blog.st-hatena.com" 40data-version="89f69427ebf1344326896140241320" 41 42 43 44 45 46 47 data-initial-state="{}" 48 49 > 50 <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#"> 51 52 53 54 55 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 56 57 58 59 60 61 62 63 <meta name="robots" content="max-image-preview:large" /> 64 65 66 <meta charset="utf-8"/> 67 <meta http-equiv="X-UA-Compatible" content="IE=7; IE=9; IE=10; IE=11" /> 68 <title>HackToTech</title> 69 70 71 <link rel="canonical" href="https://www.hacktotech.net/"/> 72 73 74 75 76 77<meta itemprop="name" content="HackToTech"/> 78 79 <meta itemprop="image" content="https://cdn.user.blog.st-hatena.com/default_entry_og_image/155647406/1577715909980632"/> 80 81 82 <meta property="og:title" content="HackToTech"/> 83<meta property="og:type" content="blog"/> 84 <meta property="og:url" content="https://www.hacktotech.net/"/> 85 86 87 88 89 <meta property="og:image" content="https://cdn.image.st-hatena.com/image/scale/edca2a88f8dc0230ccb85966912813a578c7fd12/backend=imagemagick;enlarge=0;height=1000;version=1;width=1200/https%3A%2F%2Fcdn.user.blog.st-hatena.com%2Fdefault_entry_og_image%2F155647406%2F1577715909980632"/> 90 91<meta property="og:image:alt" content="HackToTech"/> 92 <meta property="og:description" content="Hack To Technology" /> 93<meta property="og:site_name" content="HackToTech"/> 94 95 <meta name="twitter:card" content="summary_large_image" /> 96 <meta name="twitter:image" content="https://cdn.user.blog.st-hatena.com/default_entry_og_image/155647406/1577715909980632" /> <meta name="twitter:title" content="HackToTech" /> <meta name="twitter:description" content="Hack To Technology" /> <meta name="twitter:app:name:iphone" content="ã¯ã¦ãªããã°ã¢ããª" /> 97 <meta name="twitter:app:id:iphone" content="583299321" /> 98 <meta name="twitter:app:url:iphone" content="hatenablog:///open?uri=https%3A%2F%2Fwww.hacktotech.net%2F" /> <meta name="twitter:site" content="@_atr0phy_" /> 99 100 <meta name="google-site-verification" content="7P6tlmARw_v-2DggAkyXs-m7DeLWnThwfj_gURrRfdE" /> 101 102 103
104<script 105 id="embed-gtm-data-layer-loader" 106 data-data-layer-page-specific="" 107> 108(function() { 109 function loadDataLayer(elem, attrName) { 110 if (!elem) { return {}; } 111 var json = elem.getAttribute(attrName); 112 if (!json) { return {}; } 113 return JSON.parse(json); 114 } 115 116 var globalVariables = loadDataLayer( 117 document.documentElement, 118 'data-data-layer' 119 ); 120 var pageSpecificVariables = loadDataLayer( 121 document.getElementById('embed-gtm-data-layer-loader'), 122 'data-data-layer-page-specific' 123 ); 124 125 var variables = [globalVariables, pageSpecificVariables]; 126 127 if (!window.dataLayer) { 128 window.dataLayer = []; 129 } 130 131 for (var i = 0; i < variables.length; i++) { 132 window.dataLayer.push(variables[i]); 133 } 134})(); 135</script>
135 136 137<!-- Google Tag Manager -->
138<script>
vendor: 327 bytes, lines 138-142
138(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': 139new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 140j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 141'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); 142})(window,document,'script','dataLayer','
142GTM-P4CXTW
vendor: 3 bytes, line 142
142');
142</script>
142 143<!-- End Google Tag Manager --> 144 145 146 147 148 149 150 151 152 153 154 155 <link rel="shortcut icon" href="https://www.hacktotech.net/icon/favicon"> 156<link rel="apple-touch-icon" href="https://www.hacktotech.net/icon/touch"> 157<link rel="icon" sizes="192x192" href="https://www.hacktotech.net/icon/link"> 158 159 160 161<link rel="alternate" type="application/atom+xml" title="Atom" href="https://www.hacktotech.net/feed"/> 162<link rel="alternate" type="application/rss+xml" title="RSS2.0" href="https://www.hacktotech.net/rss"/> 163 164 165 166 <link rel="author" href="http://www.hatena.ne.jp/atr0phy/"> 167 168 169 170 171 172 173 174 175 176<link rel="stylesheet" type="text/css" href="https://cdn.blog.st-hatena.com/css/blog.css?version=89f69427ebf1344326896140241320"/> 177 178 179 <link rel="stylesheet" type="text/css" href="https://usercss.blog.st-hatena.com/blog_style/26006613489834982/7d2fe7769e84a69cf056ba335119ef492f269bbc"/> 180 181 182 183 184 185 186
187<script> </script>
187 188 189 190<style> 191 div#google_afc_user, 192 div.google-afc-user-container, 193 div.google_afc_image, 194 div.google_afc_blocklink { 195 display: block !important; 196 } 197</style> 198 199 200 201 202 203
203<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"HackToTech","url":"https://www.hacktotech.net/"}</script>
vendor: 71 bytes, lines 203-207
203 204 205 206 207 <script async src="https://www.googletagmanager.com/gtag/js?id=
207G-N5T771Z5Q2
vendor: 12 bytes, line 207
207"></script>
208<script> 209
vendor: 134 bytes, lines 209-213
209window.dataLayer = window.dataLayer || []; 210 function gtag(){dataLayer.push(arguments);} 211 gtag('js', new Date()); 212 213 gtag('config', '
213G-N5T771Z5Q2
vendor: 4 bytes, line 213
213');
214</script>
214 215 216 217 218</head> 219 220 <body class="page-index globalheader-off globalheader-ng-enabled"> 221 222 223 224<div id="globalheader-container" 225 data-brand="hatenablog" 226 style="display: none" 227 > 228 <iframe id="globalheader" height="37" frameborder="0" allowTransparency="true"></iframe> 229</div> 230 231 232 233 234 235 236 <div id="container"> 237 <div id="container-inner"> 238 <header id="blog-title" data-brand="hatenablog"> 239 <div id="blog-title-inner" > 240 <div id="blog-title-content"> 241 <h1 id="title"><a href="https://www.hacktotech.net/">HackToTech</a></h1> 242 243 <h2 id="blog-description">Hack To Technology</h2> 244 245 </div> 246 </div> 247</header> 248 249 250 251 252 253 254 255 256 257 258<div id="content" class="hfeed" 259 260 > 261 <div id="content-inner"> 262 <div id="wrapper"> 263 <div id="main"> 264 <div id="main-inner"> 265 266 267 268 269 270 271 272 273 <!-- google_ad_section_start --> 274 <!-- rakuten_ad_target_begin --> 275 276 277 278 279 280 281 282 283 284 <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-4800 words-600 mode-markdown entry-odd" id="entry-6801883189121681232" data-keyword-campaign="" data-uuid="6801883189121681232" data-publication-type="entry"> 285 <div class="entry-inner"> 286 <header class="entry-header"> 287 288 <div class="date entry-date first"> 289 <a href="https://www.hacktotech.net/archive/2024/07/13" rel="nofollow"> 290 <time datetime="2024-07-13T14:45:39Z" title="2024-07-13T14:45:39Z"> 291 <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">07</span><span class="hyphen">-</span><span class="date-day">13</span> 292 </time> 293 </a> 294 </div> 295 <h1 class="entry-title"> 296 <a href="https://www.hacktotech.net/entry/mockito-kotlin-value-class" class="entry-title-link bookmark">mockito-kotlinã§value classããµãã¼ãããããããã®ã§ã¡ã¢</a> 297</h1> 298 299 300 301 302 <div class="entry-categories categories"> 303 304 <a href="https://www.hacktotech.net/archive/category/mockito" class="entry-category-link category-mockito">mockito</a> 305 306 <a href="https://www.hacktotech.net/archive/category/kotlin" class="entry-category-link category-kotlin">kotlin</a> 307 308 </div> 309 310 311 312 313 314 315</header> 316 317 318 319 320 <div class="entry-content hatenablog-entry"> 321 322 <p>æ§ããã«è¨ã£ã¦ç¥ 323<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fmockito%2Fmockito-kotlin%2Fpull%2F522" title="Added value class support by LarsSven · Pull Request #522 · mockito/mockito-kotlin" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/mockito/mockito-kotlin/pull/522">github.com</a></cite> 3245.4.0ã®ãªãªã¼ã¹ã«å«ã¾ãã¦ãã 325<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fmockito%2Fmockito-kotlin%2Freleases%2Ftag%2F5.4.0" title="Release 5.4.0 · mockito/mockito-kotlin" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/mockito/mockito-kotlin/releases/tag/5.4.0">github.com</a></cite></p> 326 327<h4 id="buildgradlekts">build.gradle.kts</h4> 328 329<pre class="code lang-kotlin" data-lang="kotlin" data-unlink>plugins { 330 kotlin(<span class="synConstant">"jvm"</span>) version <span class="synConstant">"2.0.0"</span> 331} 332 333group = <span class="synConstant">"com.github.atr0phy"</span> 334version = <span class="synConstant">"1.0-SNAPSHOT"</span> 335 336repositories { 337 mavenCentral() 338} 339 340dependencies { 341 testImplementation(kotlin(<span class="synConstant">"test"</span>)) 342 testImplementation(<span class="synConstant">"org.mockito.kotlin:mockito-kotlin:5.4.0"</span>) 343} 344 345tasks.test { 346 useJUnitPlatform() 347} 348kotlin { 349 jvmToolchain(<span class="synConstant">17</span>) 350} 351</pre> 352 353 354<h4 id="ã³ã¼ã">ã³ã¼ã</h4> 355 356<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synPreProc">
356import</span> org.mockito.Mockito.mockStatic 357<span class="synPreProc">import</span> org.mockito.kotlin.any 358<span class="synPreProc">import</span> kotlin.test.Test 359<span class="synPreProc">import</span> kotlin.test.assertEquals 360 361<span class="synIdentifier">@JvmInline</span> 362<span class="synType">value</span> <span class="synType">class</span> SampleValue(<span class="synType">val</span> value: <span class="synType">String</span>) 363 364<span class="synType">object</span> SampleValueRepository { 365 <span class="synIdentifier">@JvmStatic</span> 366 <span class="synType">fun</span> save(sampleValue: SampleValue): SampleValue { 367 <span class="synStatement">return</span> sampleValue 368 } 369} 370 371<span class="synType">private</span> <span class="synType">class</span> SampleValueRepositoryTest { 372 <span class="synIdentifier">@Test</span> 373 <span class="synType">fun</span> test() { 374 <span class="synComment">// setup</span> 375 <span class="synType">val</span> expected = SampleValue(<span class="synConstant">"mocked"</span>) 376 <span class="synType">val</span> mocked = mockStatic(SampleValueRepository<span class="synStatement">::</span><span class="synType">class</span>.java) 377 mocked.`when`<SampleValue> { SampleValueRepository.save(any()) }.thenReturn(expected) 378 <span class="synComment">// ã©ã£ã¡ã§ãããã</span> 379 <span class="synComment">// mocked.`when`<SampleValue> { SampleValueRepository.save(anyValueClass()) }.thenReturn(expected)</span> 380 381 <span class="synComment">// exercise</span> 382 <span class="synType">val</span> <span class="synType">actual</span> = SampleValueRepository.save(SampleValue(<span class="synConstant">"call"</span>)) 383 384 <span class="synComment">// verify</span> 385 assertEquals(expected, <span class="synType">actual</span>) 386 } 387} 388</pre> 389 390 391<h4 id="çµæ">çµæ</h4> 392 393<h5 id="540">5.4.0</h5> 394 395<pre class="code" data-lang="" data-unlink>> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED 396> Task :compileKotlin NO-SOURCE 397> Task :compileJava NO-SOURCE 398> Task :processResources NO-SOURCE 399> Task :classes UP-TO-DATE 400> Task :processTestResources NO-SOURCE 401> Task :compileTestKotlin 402> Task :compileTestJava NO-SOURCE 403> Task :testClasses UP-TO-DATE 404> Task :test 405BUILD SUCCESSFUL in 3s 4062 actionable tasks: 2 executed 40723:35:44: ':test --tests "SampleValueTest"' ã®å®è¡ãå®äºãã¾ããã</pre> 408 409 410<h5 id="531">5.3.1</h5> 411 412<pre class="code" data-lang="" data-unlink>> Task :checkKotlinGradlePluginConfigurationErrors SKIPPED 413> Task :compileKotlin NO-SOURCE 414> Task :compileJava NO-SOURCE 415> Task :processResources NO-SOURCE 416> Task :classes UP-TO-DATE 417> Task :processTestResources NO-SOURCE 418> Task :compileTestKotlin 419> Task :compileTestJava NO-SOURCE 420> Task :testClasses UP-TO-DATE 421 422 423Misplaced or misused argument matcher detected here: 424 425-> at SampleValueTest.test$lambda$0(SampleValueTest.kt:32) 426 427You cannot use argument matchers outside of verification or stubbing. 428Examples of correct usage of argument matchers: 429 when(mock.get(anyInt())).thenReturn(null); 430 doThrow(new RuntimeException()).when(mock).someVoidMethod(any()); 431 verify(mock).someMethod(contains("foo")) 432 433This message may appear after an NullPointerException if the last matcher is returning an object 434like any() but the stubbed method signature expect a primitive argument, in this case, 435use primitive alternatives. 436 when(mock.get(any())); // bad use, will raise NPE 437 when(mock.get(anyInt())); // correct usage use 438 439Also, this error might show up because you use argument matchers with methods that cannot be mocked. 440Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode(). 441Mocking methods declared on non-public parent classes is not supported. 442 443org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 444Misplaced or misused argument matcher detected here: 445 446-> at SampleValueTest.test$lambda$0(SampleValueTest.kt:32) 447 448You cannot use argument matchers outside of verification or stubbing. 449Examples of correct usage of argument matchers: 450 when(mock.get(anyInt())).thenReturn(null); 451 doThrow(new RuntimeException()).when(mock).someVoidMethod(any()); 452 verify(mock).someMethod(contains("foo")) 453 454This message may appear after an NullPointerException if the last matcher is returning an object 455like any() but the stubbed method signature expect a primitive argument, in this case, 456use primitive alternatives. 457 when(mock.get(any())); // bad use, will raise NPE 458 when(mock.get(anyInt())); // correct usage use 459 460Also, this error might show up because you use argument matchers with methods that cannot be mocked. 461Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode(). 462Mocking methods declared on non-public parent classes is not supported. 463 464 at SampleValueTest.test(SampleValueTest.kt:22) 465 at java.base/java.lang.reflect.Method.invoke(Method.java:568) 466 at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) 467 at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) 468 469 470OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended 471> Task :test FAILED 472SampleValueTest > test() FAILED 473 org.mockito.exceptions.misusing.InvalidUseOfMatchersException at SampleValueTest.kt:22
4741 test completed, 1 failed 475</pre> 476 477 478<p>å ¬å¼ã§ãµãã¼ããããã®å¬ãã</p> 479 480 481 482 483 484</div> 485 486 487 <footer class="entry-footer"> 488 489 <div class="entry-tags-wrapper"> 490 <div class="entry-tags"> </div> 491</div> 492 493 <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> 494 <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="atr0phy" >atr0phy</span></span> 495 <span class="entry-footer-time"><a href="https://www.hacktotech.net/entry/mockito-kotlin-value-class"><time data-relative datetime="2024-07-13T14:45:39Z" title="2024-07-13T14:45:39Z" class="updated">2024-07-13 23:45</time></a></span> 496 497 498 499</p> 500 501 502 <div 503 class="hatena-star-container" 504 data-hatena-star-container 505 data-hatena-star-url="https://www.hacktotech.net/entry/mockito-kotlin-value-class" 506 data-hatena-star-title="mockito-kotlinã§value classããµãã¼ãããããããã®ã§ã¡ã¢" 507 data-hatena-star-variant="profile-icon" 508 data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" 509 ></div> 510 511 512 513<div class="social-buttons"> 514 515 516 <div class="social-button-item"> 517 <a href="https://b.hatena.ne.jp/entry/s/www.hacktotech.net/entry/mockito-kotlin-value-class" class="hatena-bookmark-button" data-hatena-bookmark-url="https://www.hacktotech.net/entry/mockito-kotlin-value-class" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å "><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å " width="20" height="20" style="border: none;" /></a> 518 </div> 519 520 521 522 523 524 <div class="social-button-item"> 525 <a 526 class="entry-share-button entry-share-button-twitter test-share-button-twitter" 527 href="https://x.com/intent/tweet?text=mockito-kotlin%E3%81%A7value+class%E3%81%8C%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88%E3%81%95%E3%82%8C%E3%81%9F%E3%82%89%E3%81%97%E3%81%84%E3%81%AE%E3%81%A7%E3%83%A1%E3%83%A2+-+HackToTech&url=https%3A%2F%2Fwww.hacktotech.net%2Fentry%2Fmockito-kotlin-value-class" 528 title="Xï¼Twitterï¼ã§æç¨¿ãã" 529 ></a> 530 </div> 531 532 533 534 535 536 537</div> 538 539 540 541 <div class="customized-footer"> 542 543 544 </div> 545 546 547 </footer> 548 549 </div> 550</article> 551 552 553 554 555 556 557 558 <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-8000 words-800 mode-markdown entry-even" id="entry-6801883189109177200" data-keyword-campaign="" data-uuid="6801883189109177200" data-publication-type="entry"> 559 <div class="entry-inner"> 560 <header class="entry-header"> 561 562 <div class="date entry-date first"> 563 <a href="https://www.hacktotech.net/archive/2024/05/25" rel="nofollow"> 564 <time datetime="2024-05-25T12:34:21Z" title="2024-05-25T12:34:21Z"> 565 <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">05</span><span class="hyphen">-</span><span class="date-day">25</span> 566 </time> 567 </a> 568 </div> 569 <h1 class="entry-title"> 570 <a href="https://www.hacktotech.net/entry/sbom-memo" class="entry-title-link bookmark">SBOMå¨ããè¦ã¦ãã®ã§ã¡ã¢</a> 571</h1> 572 573 574 575 576 <div class="entry-categories categories"> 577 578 <a href="https://www.hacktotech.net/archive/category/SBOM" class="entry-category-link category-SBOM">SBOM</a> 579 580 </div> 581 582 583 584 585 586 587</header> 588 589 590 591 592 <div class="entry-content hatenablog-entry"> 593 594 <p>Spring Boot 3.3ã§SBOMããµãã¼ããããã¨èããã®ã§ãã©ããªãããªã®ãã試ãã¦ããã®ã§ã¡ã¢<br/> 595(SBOMã«ã¤ãã¦è©³ããæ¸ãã¦ããè¨äºã§ã¯ãªãã®ã§ããããã£ãè¨äºãè¦ããå ´åã¯ãã©ã¦ã¶ããã¯æ¨å¥¨) 596<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fspring.io%2Fblog%2F2024%2F05%2F24%2Fsbom-support-in-spring-boot-3-3" title="SBOM support in Spring Boot 3.3" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://spring.io/blog/2024/05/24/sbom-support-in-spring-boot-3-3">spring.io</a></cite></p> 597 598<p>SBOMã«ã¤ãã¦ã¯çµç£çã®è³æãè¦ãã®ãè¯ãããã ã£ã 599<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fwww.meti.go.jp%2Fpress%2F2023%2F07%2F20230728004%2F20230728004.html" title="ãã½ããã¦ã§ã¢ç®¡çã«åããSBOMï¼Software Bill of Materialsï¼ã®å°å ¥ã«é¢ããæå¼ããçå®ãã¾ãã ï¼METI/çµæ¸ç£æ¥çï¼" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://www.meti.go.jp/press/2023/07/20230728004/20230728004.html">www.meti.go.jp</a></cite></p> 600 601<p>ã§ããã®è¾ºãå ¨ã詳ãããªãã¦ä»åããä½ãã©ããµãã¼ããããã®ã
601ãå ¨ãããããªãã£ãã®ã§ãæãåãããªãã試ãã¦ããæã<br/> 602対象㮠<code>gradle plugin</code> ãå ¥ããã° <code>bootJar</code> ã®ã¿ã¹ã¯å®è¡æã«<br/> 603<code>JAR</code> ã® <code>META-INF/sbom/bom.json</code> ( <code>json</code> ãã¯æå®ã«ããã¯ã)ã«SBOMãåãè¾¼ãã§ãããã¨ãã話ã ã£ã 604<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2FCycloneDX%2Fcyclonedx-gradle-plugin" title="GitHub - CycloneDX/cyclonedx-gradle-plugin: Creates CycloneDX Software Bill of Materials (SBOM) from Gradle projects" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/CycloneDX/cyclonedx-gradle-plugin">github.com</a></cite></p> 605 606<p>ãã¨ã¯ <code>spring-boot-starter-actuator</code> å ¥ã㦠<code>application.properties</code> è¨å®ãã¦ããã°actuatorçµç±ã§å ¬éã§ããããã«ãªã£ã¦ãããã<br/> 607å é¨çã«è¦ããã ããªãç¹ã«APIã§åå¾ã§ããªãã¦ãè¯ããããªæ°ããã</p> 608 609<p>æ®æ®µã¯ <code>trivy</code> ã§ <code>JAR</code> ã®å ¥ã£ãã³ã³ããã¤ã¡ã¼ã¸ã®<a href="https://aquasecurity.github.io/trivy/v0.40/docs/vulnerability/languages/java/">èå¼±æ§ã¹ãã£ã³</a>ããã¦ä½µãã¦ãã§ãã¯ãã¦ãããã<br/> 610SBOMä½ã£ã¦ãã£ã¡ã <code>trivy</code> ã <code>osv-scanner</code> ã«é£ãããã»ããè¯ãã£ããããã®ãæ°ã«ãªã</p> 611 612<h3 id="é©å½ã«CVEããããã¼ã¸ã§ã³ã®ã©ã¤ãã©ãªã使ã£ãã¢ããªã±ã¼ã·ã§ã³ã§SBOMãä½ã£ã¦è©¦ãã¦è¦ã">é©å½ã«CVEããããã¼ã¸ã§ã³ã®ã©ã¤ãã©ãªã使ã£ãã¢ããªã±ã¼ã·ã§ã³ã§ãSBOMãä½ã£ã¦è©¦ãã¦è¦ã</h3> 613 614<p>ä½ã£ãSBOM(ç´æ¥åãè¾¼ãã¨ããªãé·ãã®ã§gistã¸ã®ãªã³ã¯) 615<a href="https://gist.github.com/atr0phy/0d853f5c251e7e20116d50ae78aabf58#file-sbom-json">https://gist.github.com/atr0phy/0d853f5c251e7e20116d50ae78aabf58#file-sbom-json</a></p> 616 617<h4 id="trivy">trivy</h4> 618 619<pre class="code bash" data-lang="bash" data-unlink>$ trivy sbom bom.32.json 6202024-05-25T20:44:07+09:00 INFO Vulnerability scanning is enabled 6212024-05-25T20:44:07+09:00 INFO Detected SBOM format format="cyclonedx-json" 6222024-05-25T20:44:07+09:00 WARN Third-party SBOM may lead to inaccurate vulnerability detection 6232024-05-25T20:44:07+09:00 WARN Recommend using Trivy to generate SBOMs 624.... 625 626Java (jar) 627 628Total: 8 (UNKNOWN: 0, LOW: 0, MEDIUM: 2, HIGH: 5, CRITICAL: 1) 629 630ââââââââââââââââââââââââââââââââââââââââââââââââââ¬âââââââââââââââââ¬âââââââââââ¬âââââââââ¬ââââââââââââââââââââ¬ââââââââââââââââââââââââââââââââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 631â Library â Vulnerability â Severity â Status â Installed Version â Fixed Version â Title â 632ââââââââââââââââââââââââââââââââââââââââââââââââââ¼âââââââââââââââââ¼âââââââââââ¼âââââââââ¼ââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠633â ch.qos.logback:logback-classic â CVE-2023-6378 â HIGH â fixed â 1.4.11 â 1.3.12, 1.4.12, 1.2.13 â logback: serialization vulnerability in logback receiver â 634â â â â â â â https://avd.aquasec.com/nvd/cve-2023-6378 â 635âââââââââââââââââââââââââââââââââââââââââââââââââ⤠â â â â â â 636â ch.qos.logback:logback-core â â â â â â â 637â â â â â â â â 638ââââââââââââââââââââââââââââââââââââââââââââââââââ¼âââââââââââââââââ¼ââââââââââ⤠âââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠639â org.apache.tomcat.embed:tomcat-embed-core â CVE-2024-24549 â MEDIUM â â 10.1.16 â 8.5.99, 9.0.86, 10.1.19, 11.0.0-M17 â : Apache Tomcat: HTTP/2 header handling DoS â 640â â â â â â â https://avd.aquasec.com/nvd/cve-2024-24549 â 641ââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââ⤠â â âââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠642â org.apache.tomcat.embed:tomcat-embed-websocket â CVE-2024-23672 â â â â 11.0.0-M17, 10.1.19, 9.0.86, 8.5.99 â Apache Tomcat: WebSocket DoS with incomplete closing â 643â â â â â â â handshake â 644â â â â â â â https://avd.aquasec.com/nvd/cve-2024-23672 â 645ââââââââââââââââââââââââââââââââââââââââââââââââââ¼âââââââââââââââââ¼ââââââââââ⤠âââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠646â org.postgresql:postgresql â CVE-2024-1597 â CRITICAL â â 42.7.1 â 42.2.28, 42.3.9, 42.4.4, 42.5.5, 42.6.1, 42.7.2 â pgjdbc: PostgreSQL JDBC Driver allows attacker to inject SQL â 647â â â â â â â if using PreferQueryMode=SIMPLE... â 648â â â â â â â https://avd.aquasec.com/nvd/cve-2024-1597 â 649ââââââââââââââââââââââââââââââââââââââââââââââââââ¼âââââââââââââââââ¼ââââââââââ⤠âââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠650â org.springframework:spring-web â CVE-2024-22243 â HIGH â â 6.1.1 â 6.1.4, 6.0.17, 5.3.32 â springframework: URL Parsing with Host Validation â 651â â â â â â â https://avd.aquasec.com/nvd/cve-2024-22243 â 652â âââââââââââââââââ⤠â â âââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠653â â CVE-2024-22259 â â â â 6.1.5, 6.0.18, 5.3.33 â springframework: URL Parsing with Host Validation â 654â â â â â â â https://avd.aquasec.com/nvd/cve-2024-22259 â 655â âââââââââââââââââ⤠â â âââââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ⤠656â â CVE-2024-22262 â â â â 5.3.34, 6.0.19, 6.1.6 â springframework: URL Parsing with Host Validation â 657â â â â â â â https://avd.aquasec.com/nvd/cve-2024-22262 â 658ââââââââââââââââââââââââââââââââââââââââââââââââââ´âââââââââââââââââ´âââââââââââ´âââââââââ´ââââââââââââââââââââ´ââââââââââââââââââââââââââââââââââââââââââââââââââ´âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 659</pre> 660 661 662<p>trivyã®æ¹ãä¿®æ£ãã¼ã¸ã§ã³ãåºã¦ãã¦è¦ªåã ããçç¥ããç®æã«âã¿ãããªHASHã®WARNãåºã¦ããã®ã ãè¦ã¥ããã®ã§ã©ãã«ãããã»ããè¯ãããã ã£ã</p> 663 664<pre class="code bash" data-lang="bash" data-unlink>2024-05-25T20:43:52+09:00 WARN Unsupported hash algorithm algorithm="SHA3-384" 6652024-05-25T20:43:52+09:00 WARN Unsupported hash algorithm algorithm="SHA3-256" 6662024-05-25T20:43:52+09:00 WARN Unsupported hash algorithm algorithm="SHA3-512"</pre> 667 668 669<h4 id="osv-scanner">osv-scanner</h4> 670 671<pre class="code bash" data-lang="bash" data-unlink>$ osv-scanner scan --sbom bom.32.json 672Scanned /home/atr0phy/workspace/spring-boot-33/build/reports/bom.32.json as CycloneDX SBOM and found 40 packages 673âââââââââââââââââââââââââââââââââââââââ¬âââââââ¬ââââââââââââ¬âââââââââââââââââââââââââââââââââââââââââââââââââ¬ââââââââââ¬ââââââââââââââ® â 674â OSV URL â CVSS â ECOSYSTEM â PACKAGE â VERSION â SOURCE â 675âââââââââââââââââââââââââââââââââââââââ¼âââââââ¼ââââââââââââ¼âââââââââââââââââââââââââââââââââââââââââââââââââ¼ââââââââââ¼âââââââââââââ⤠â 676â https://osv.dev/GHSA-24rp-q3w6-vc56 â 10.0 â Maven â org.postgresql:postgresql â 42.7.1 â bom.32.json â 677â https://osv.dev/GHSA-vmq6-5m68-f53m â 7.1 â Maven â ch.qos.logback:logback-core â 1.4.11 â bom.32.json â 678â https://osv.dev/GHSA-7w75-32cg-r6g2 â â Maven â org.apache.tomcat.embed:tomcat-embed-core â 10.1.16 â bom.32.json â 679â https://osv.dev/GHSA-2wrp-6fg6-hmc5 â 8.1 â Maven â org.springframework:spring-web â 6.1.1 â bom.32.json â 680â https://osv.dev/GHSA-ccgv-vj62-xf9h â 8.1 â Maven â org.springframework:spring-web â 6.1.1 â bom.32.json â 681â https://osv.dev/GHSA-hgjh-9rj2-g67j â 8.1 â Maven â org.springframework:spring-web â 6.1.1 â bom.32.json â 682â https://osv.dev/GHSA-v682-8vv8-vpwr â â Maven â org.apache.tomcat.embed:tomcat-embed-websocket â 10.1.16 â bom.32.json â 683â https://osv.dev/GHSA-vmq6-5m68-f53m â 7.1 â Maven â ch.qos.logback:logback-classic â 1.4.11 â bom.32.json â 684â°ââââââââââââââââââââââââââââââââââââââ´âââââââ´ââââââââââââ´âââââââââââââââââââââââââââââââââââââââââââââââââ´ââââââââââ´âââââââââââââ⯠â</pre> 685 686 687<h3 id="試ãã¦ãã-buildgradlekts">試ãã¦ãã <code>build.gradle.kts</code></h3> 688 689<p>ä¸è¨ã®
689SBOMçææã¯ãè¤æ°ã®èå¼±æ§ãè¦ããã£ãã®ã§ <code>id("org.springframework.boot") version "3.2.0"</code> ã使ç¨ãã</p> 690 691<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synPreProc">import</span> org.jetbrains.kotlin.gradle.tasks.KotlinCompile 692 693plugins { 694 id(<span class="synConstant">"org.springframework.boot"</span>) version <span class="synConstant">"3.3.0"</span> 695 id(<span class="synConstant">"io.spring.dependency-management"</span>) version <span class="synConstant">"1.1.5"</span> 696 kotlin(<span class="synConstant">"jvm"</span>) version <span class="synConstant">"1.9.24"</span> 697 kotlin(<span class="synConstant">"plugin.spring"</span>) version <span class="synConstant">"1.9.24"</span> 698 id(<span class="synConstant">"org.cyclonedx.bom"</span>) version <span class="synConstant">"1.8.2"</span> 699} 700 701group = <span class="synConstant">"com.github.atr0phy"</span> 702version = <span class="synConstant">"0.0.1-SNAPSHOT"</span> 703 704java { 705 sourceCompatibility = JavaVersion.VERSION_17 706} 707 708repositories { 709 mavenCentral() 710} 711 712dependencies { 713 implementation(<span class="synConstant">"org.springframework.boot:spring-boot-starter-web"</span>) 714 <span class="synComment">// implementation("org.springframework.boot:spring-boot-starter-actuator")</span> 715 implementation(<span class="synConstant">"com.fasterxml.jackson.module:jackson-module-kotlin"</span>) 716 implementation(<span class="synConstant">"org.jetbrains.kotlin:kotlin-reflect"</span>) 717 <span class="synComment">// ããã¨CVEã®å«ã¾ãããã¼ã¸ã§ã³ãå ¥ãã</span> 718 implementation(<span class="synConstant">"org.postgresql:postgresql:42.7.1"</span>) 719 testImplementation(<span class="synConstant">"org.springframework.boot:spring-boot-starter-test"</span>) 720 testRuntimeOnly(<span class="synConstant">"org.junit.platform:junit-platform-launcher"</span>) 721} 722 723tasks.withType<KotlinCompile> { 724 kotlinOptions { 725 freeCompilerArgs <span class="synStatement">+</span>= <span class="synConstant">"-Xjsr305=strict"</span> 726 jvmTarget = <span class="synConstant">"17"</span> 727 } 728} 729 730tasks.withType<Test> { 731 useJUnitPlatform() 732} 733 734tasks.cyclonedxBom { 735 <span class="synComment">// ã»ã¼å ¬å¼ã®ãµã³ãã«éã</span> 736 setIncludeConfigs(listOf(<span class="synConstant">"runtimeClasspath"</span>)) 737 setSkipConfigs(listOf(<span class="synConstant">"compileClasspath"</span>, <span class="synConstant">"testCompileClasspath"</span>)) 738 setProjectType(<span class="synConstant">"application"</span>) 739 setSchemaVersion(<span class="synConstant">"1.5"</span>) 740 setOutputName(<span class="synConstant">"bom"</span>) 741 setOutputFormat(<span class="synConstant">"json"</span>) 742 setIncludeBomSerialNumber(<span class="synConstant">true</span>) 743 setIncludeLicenseText(<span class="synConstant">true</span>) 744 setComponentVersion(<span class="synConstant">"2.0.0"</span>) 745} 746</pre> 747 748 749 750 751 752 753</div> 754 755 756 <footer class="entry-footer"> 757 758 <div class="entry-tags-wrapper"> 759 <div class="entry-tags"> </div> 760</div> 761 762 <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> 763 <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="atr0phy" >atr0phy</span></span> 764 <span class="entry-footer-time"><a href="https://www.hacktotech.net/entry/sbom-memo"><time data-relative datetime="2024-05-25T12:34:21Z" title="2024-05-25T12:34:21Z" class="updated">2024-05-25 21:34</time></a></span> 765 766 767 768</p> 769 770 771 <div 772 class="hatena-star-container" 773 data-hatena-star-container 774 data-hatena-star-url="https://www.hacktotech.net/entry/sbom-memo" 775 data-hatena-star-title="SBOMå¨ããè¦ã¦ãã®ã§ã¡ã¢" 776 data-hatena-star-variant="profile-icon" 777 data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" 778 ></div> 779 780 781 782<div class="social-buttons"> 783 784
785 <div class="social-button-item"> 786 <a href="https://b.hatena.ne.jp/entry/s/www.hacktotech.net/entry/sbom-memo" class="hatena-bookmark-button" data-hatena-bookmark-url="https://www.hacktotech.net/entry/sbom-memo" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å "><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å " width="20" height="20" style="border: none;" /></a> 787 </div> 788 789 790 791 792 793 <div class="social-button-item"> 794 <a 795 class="entry-share-button entry-share-button-twitter test-share-button-twitter" 796 href="https://x.com/intent/tweet?text=SBOM%E5%91%A8%E3%82%8A%E3%82%92%E8%A6%8B%E3%81%A6%E3%81%9F%E3%81%AE%E3%81%A7%E3%83%A1%E3%83%A2+-+HackToTech&url=https%3A%2F%2Fwww.hacktotech.net%2Fentry%2Fsbom-memo" 797 title="Xï¼Twitterï¼ã§æç¨¿ãã" 798 ></a> 799 </div> 800 801 802 803 804 805 806</div> 807 808 809 810 <div class="customized-footer"> 811 812 813 </div> 814 815 816 </footer> 817 818 </div> 819</article> 820 821 822 823 824 825 826 827 <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-1200 words-100 mode-markdown entry-odd" id="entry-6801883189102630983" data-keyword-campaign="" data-uuid="6801883189102630983" data-publication-type="entry"> 828 <div class="entry-inner"> 829 <header class="entry-header"> 830 831 <div class="date entry-date first"> 832 <a href="https://www.hacktotech.net/archive/2024/04/30" rel="nofollow"> 833 <time datetime="2024-04-30T10:07:50Z" title="2024-04-30T10:07:50Z"> 834 <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">04</span><span class="hyphen">-</span><span class="date-day">30</span> 835 </time> 836 </a> 837 </div> 838 <h1 class="entry-title"> 839 <a href="https://www.hacktotech.net/entry/use-spring-milestone-version" class="entry-title-link bookmark">Springã®milestoneã®ãã¼ã¸ã§ã³ã試ãã¦ãã®ã§ã¡ã¢</a> 840</h1> 841 842 843 844 845 <div class="entry-categories categories"> 846 847 <a href="https://www.hacktotech.net/archive/category/spring" class="entry-category-link category-spring">spring</a> 848 849 </div> 850 851 852 853 854 855 856</header> 857 858 859 860 861 <div class="entry-content hatenablog-entry"> 862 863 <p>å人çãªåå¿é²<br/> 864<code>6.2.0-M1</code> ã®æ°æ©è½ã® <code>@Fallback</code> 試ãããã£ããã<br/> 865ããããã©ãã«ã©ã¤ãã©ãªãä¸ãã£ã¦ããã®ããç¥ããªãã£ãã®ã§ã¡ã¢ 866<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fspring-projects%2Fspring-framework%2Freleases%2Ftag%2Fv6.2.0-M1" title="Release v6.2.0-M1 · spring-projects/spring-framework" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/spring-projects/spring-framework/releases/tag/v6.2.0-M1">github.com</a></cite></p> 867 868<p>æ®éã«âã«è¨è¼ããããªãã¸ããªã«ããã£ã¦ããã®ã§ã 869<iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fspring-projects%2Fspring-framework%2Fwiki%2FSpring-Framework-Artifacts%23spring-repositories" title="Spring Framework Artifacts" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/spring-projects/spring-framework/wiki/Spring-Framework-Artifacts#spring-repositories">github.com</a></cite></p> 870 871<p>ãã¨ã¯ãã¤ãéã <code>build.gradle.kts</code> ã«è¨è¼ããã°è¯ã</p> 872 873<pre class="code lang-kotlin" data-lang="kotlin" data-unlink>repositories { 874 mavenCentral() 875 maven { 876 url = uri(<span class="synConstant">"https://repo.spring.io/milestone"</span>) 877 } 878} 879 880dependencies { 881 implementation(<span class="synConstant">"org.springframework.boot:spring-boot-starter"</span>) 882 implementation(<span class="synConstant">"org.springframework.boot:spring-boot-starter-web"</span>) 883 implementation(<span class="synConstant">"org.jetbrains.kotlin:kotlin-reflect"</span>) 884 implementation(<span class="synConstant">"org.springframework:spring-aop:6.2.0-M1"</span>) 885 implementation(<span class="synConstant">"org.springframework:spring-beans:6.2.0-M1"</span>) 886 implementation(<span class="synConstant">"org.springframework:spring-expression:6.2.0-M1"</span>) 887 implementation(<span class="synConstant">"org.springframework:spring-context:6.2.0-M1"</span>) 888 implementation(<span class="synConstant">"org.springframework:spring-core:6.2.0-M1"</span>) 889 implementation(<span class="synConstant">"org.springframework:spring-jcl:6.2.0-M1"</span>) 890 testImplementation(<span class="synConstant">"org.springframework.boot:spring-boot-starter-test"</span>) 891} 892</pre> 893 894 895 896 897 898 899</div> 900 901 902 <footer class="entry-footer"> 903 904 <div class="entry-tags-wrapper"> 905 <div class="entry-tags"> </div> 906</div> 907 908 <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> 909 <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="atr0phy" >atr0phy</span></span> 910 <span class="entry-footer-time"><a href="https://www.hacktotech.net/entry/use-spring-milestone-version"><time data-relative datetime="2024-04-30T10:07:50Z" title="2024-04-30T10:07:50Z" class="updated">2024-04-30 19:07</time></a></span> 911 912 913 914</p> 915 916 917 <div 918 class="hatena-star-container" 919 data-hatena-star-container 920 data-hatena-star-url="https://www.hacktotech.net/entry/use-spring-milestone-version" 921 data-hatena-star-title="Springã®milestoneã®ãã¼ã¸ã§ã³ã試ãã¦ãã®ã§ã¡ã¢" 922 data-hatena-star-variant="profile-icon" 923 data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" 924 ></div> 925 926 927 928<div class="social-buttons"> 929 930
931 <div class="social-button-item"> 932 <a href="https://b.hatena.ne.jp/entry/s/www.hacktotech.net/entry/use-spring-milestone-version" class="hatena-bookmark-button" data-hatena-bookmark-url="https://www.hacktotech.net/entry/use-spring-milestone-version" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å "><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å " width="20" height="20" style="border: none;" /></a> 933 </div> 934 935 936 937 938 939 <div class="social-button-item"> 940 <a 941 class="entry-share-button entry-share-button-twitter test-share-button-twitter" 942 href="https://x.com/intent/tweet?text=Spring%E3%81%AEmilestone%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%9F%E3%81%AE%E3%81%A7%E3%83%A1%E3%83%A2+-+HackToTech&url=https%3A%2F%2Fwww.hacktotech.net%2Fentry%2Fuse-spring-milestone-version" 943 title="Xï¼Twitterï¼ã§æç¨¿ãã" 944 ></a> 945 </div> 946 947 948 949 950 951 952</div> 953 954 955 956 <div class="customized-footer"> 957 958 959 </div> 960 961 962 </footer> 963 964 </div> 965</article> 966 967 968 969 970 971 972 973 <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-2800 words-400 mode-markdown entry-even" id="entry-6801883189095011317" data-keyword-campaign="" data-uuid="6801883189095011317" data-publication-type="entry"> 974 <div class="entry-inner"> 975 <header class="entry-header"> 976 977 <div class="date entry-date first"> 978 <a href="https://www.hacktotech.net/archive/2024/03/31" rel="nofollow"> 979 <time datetime="2024-03-31T08:55:26Z" title="2024-03-31T08:55:26Z"> 980 <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">03</span><span class="hyphen">-</span><span class="date-day">31</span> 981 </time> 982 </a> 983 </div> 984 <h1 class="entry-title"> 985 <a href="https://www.hacktotech.net/entry/spring-boot-exception-translator-for-repository-annotation" class="entry-title-link bookmark">SpringBootã§@Repositoryãã¤ããã¯ã©ã¹ã®ã¡ã½ããããæããããä¾å¤ã夿ãã¦æãç´ã</a> 986</h1> 987 988 989 990 991 <div class="entry-categories categories"> 992 993 <a href="https://www.hacktotech.net/archive/category/spring-boot" class="entry-category-link category-spring-boot">spring-boot</a> 994 995 <a href="https://www.hacktotech.net/archive/category/kotlin" class="entry-category-link category-kotlin">kotlin</a> 996 997 </div> 998 999 1000 1001 1002 1003 1004</header> 1005 1006 1007 1008 1009 <div class="entry-content hatenablog-entry"> 1010 1011 <p>å人çãªåå¿é²</p> 1012 1013<p>ã¬ã¤ã¤ã¼ãã¢ã¼ããã¯ãã£ã§ã¢ããªã±ã¼ã·ã§ã³ãä½ã£ã¦ãã¦ã<br/> 1014è³å¦ä¸¡è«ããã¨æãããã¡ã¤ã³å±¤ã®ããªãã¼ã·ã§ã³ã使æã¨DBããã®åæ§ææã«ãã§ãã¯ãã¦ãã¦ã<br/> 1015使æã¯ä¾å¤ããã®ã¾ã¾æãããããåæ§ææã¯ããããããªãã¨æã£ã¦ããã®ã§ã表é¡ã®ãããªãã¨ããããã£ã<br/> 1016(å¤ãªãã¼ã¿ãå ¥ã£ããããªããã°ãããªãã¨ãããªãã¦ãè¯ãããç¹æ®ãªã±ã¼ã¹ã§èµ·ãã£ããããçºãã¢ã¤ã¢ã¤ãã¦ããã®ã§èª¿ã¹ã¦ãã)</p> 1017 1018<p>ä¾ãã°ãâã¿ãããªã¯ã©ã¹ããã¡ã¤ã³ã¨ãã¦æã£ã¦ãã¦ã <code>init</code> ã§ããªãã¼ã·ã§ã³ãè¡ã£ã¦ããã¨ãã<br/> 1019ããªãã¼ã·ã§ã³ã«å¤±æããå ´åã¯ã <code>DomainException</code> ãã¹ãã¼ãã</p> 1020 1021<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synType">data</span> <span class="synType">class</span> UserId(<span class="synType">val</span> value: UUID) { 1022 <span class="synType">companion</span> <span class="synType">object</span> { 1023 <span class="synType">fun</span> generate(): UserId { 1024 <span class="synStatement">return</span> UserId(UUID.randomUUID()) 1025 } 1026 } 1027} 1028 1029<span class="synType">data</span> <span class="synType">class</span> User( 1030 <span class="synType">val</span> id: UserId, 1031 <span class="synType">val</span> name: UserName, 1032) { 1033 <span class="synType">companion</span> <span class="synType">object</span> {
1034 <span class="synType">fun</span> of( 1035 name: UserName, 1036 ): User { 1037 <span class="synStatement">return</span> User( 1038 id = UserId.generate(), 1039 name = name, 1040 ) 1041 } 1042 } 1043} 1044 1045<span class="synType">data</span> <span class="synType">class</span> UserName(<span class="synType">val</span> value: <span class="synType">String</span>) { 1046 <span class="synType">companion</span> <span class="synType">object</span> { 1047 <span class="synType">private</span> <span class="synType">const</span> <span class="synType">val</span> MIN_LENGTH = <span class="synConstant">1</span> 1048 <span class="synType">private</span> <span class="synType">const</span> <span class="synType">val</span> MAX_LENGTH = <span class="synConstant">256</span> 1049 1050 <span class="synType">fun</span> of(value: <span class="synType">String</span>): UserName { 1051 <span class="synStatement">return</span> UserName(value) 1052 } 1053 } 1054 1055 <span class="synType">init</span> { 1056 <span class="synStatement">if</span> (MIN_LENGTH<span class="synStatement"> ></span> value.length <span class="synStatement">||</span> 1057 MAX_LENGTH <span class="synStatement">< </span>value.length) { 1058 <span class="synStatement">throw</span> DomainException( 1059 message = <span class="synConstant">"ã¦ã¼ã¶åã¯</span><span class="synIdentifier">${</span>MIN_LENGTH<span class="synIdentifier">}</span><span class="synConstant">以ä¸</span><span class="synIdentifier">${</span>MAX_LENGTH<span class="synIdentifier">}</span><span class="synConstant">以ä¸ã®é·ãã§ããå¿ è¦ãããã¾ã"</span>, 1060 ) 1061 } 1062 } 1063} 1064</pre> 1065 1066 1067<p>ãªãã¸ããªã®ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯ã¨ããããä¿åã¨IDæ¤ç´¢ã ãç¨æãã</p> 1068 1069<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synType">interface</span> UserRepository { 1070 <span class="synType">fun</span> findById(id: UserId): User 1071 <span class="synType">fun</span> save(user: User) 1072} 1073</pre> 1074 1075 1076<p>å®è£ ã¯ä»¥ä¸</p> 1077 1078<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synIdentifier">@Repository</span> 1079<span class="synType">class</span> UserRepositoryImpl: UserRepository { 1080 <span class="synType">private</span> <span class="synType">val</span> user1 = UserEntity( 1081 id = UUID.fromString(<span class="synConstant">"a687b0bc-0887-483c-8851-4604657162c1"</span>), 1082 name = <span class="synConstant">""</span>, <span class="synComment">// ãªããããã®çç±ã§å ã å ¥ã£ã¦ããã¨ãã</span> 1083 ) 1084 1085 <span class="synType">private</span> <span class="synType">val</span> user2 = UserEntity( 1086 id = UUID.fromString(<span class="synConstant">"bb1304ea-8d78-4b99-b4d1-ce4000c1c9ab"</span>), 1087 name = <span class="synConstant">"ãã¹ãã¦ã¼ã¶"</span>, 1088 ) 1089 1090 <span class="synType">private</span> <span class="synType">val</span> map = ConcurrentHashMap( 1091 mapOf( 1092 <span class="synType">Pair</span>( 1093 user1.id, 1094 user1, 1095 ), 1096 <span class="synType">Pair</span>( 1097 user2.id, 1098 user2, 1099 ), 1100 ) 1101 ) 1102 <span class="synType">override</span> <span class="synType">fun</span> findById(id: UserId): User { 1103 <span class="synStatement">return</span> map.getOrElse(id.value) { <span class="synStatement">throw</span> <span class="synType">RuntimeException</span>(<span class="synConstant">"ã¦ã¼ã¶ãåå¨ãã¾ãã"</span>) } 1104 .toUser() 1105 } 1106 1107 <span class="synType">override</span> <span class="synType">fun</span> save(user: User) { 1108 <span class="synType">val</span> entity = UserEntity( 1109 id = user.id.value, 1110 name = user.name.value(), 1111 ) 1112 1113 <span class="synStatement">if</span>(map.putIfAbsent(user.id.value, entity) <span class="synStatement">!=</span> <span class="synConstant">null</span>) {
1114 <span class="synStatement">throw</span> <span class="synType">RuntimeException</span>(<span class="synConstant">"ã¦ã¼ã¶ããã§ã«åå¨ãã¾ã"</span>) 1115 } 1116 } 1117} 1118</pre> 1119 1120 1121<p>ä»åã¯DBã使ã£ã¦ãªãããDBã使ã£ãå ´åãæ³å®ãã¦ãDBç¨ã®ã¢ãã«ãç¨æãã<br/> 1122ããã§DBã®ã¢ãã«ãããã¡ã¤ã³ã¢ãã«ã®å¤æãããããããªãã¼ã·ã§ã³ã«å¤±æããå ´å㯠<code>DomainException</code> ãã¹ãã¼ããã</p> 1123 1124<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synType">data</span> <span class="synType">class</span> UserEntity ( 1125 <span class="synType">val</span> id: UUID, 1126 <span class="synType">val</span> name: <span class="synType">String</span>, 1127) { 1128 <span class="synType">fun</span> toUser(): User { 1129 <span class="synStatement">return</span> User( 1130 id = UserId(value = id), 1131 name = UserName(value = name), 1132 ) 1133 } 1134} 1135</pre> 1136 1137 1138<p>ã¢ãã«ã®å¤æãããã®ã¯ <code>@Repository</code> ã®ã¢ããã¼ã·ã§ã³ãã¤ããã¯ã©ã¹ãªã®ã§ã<br/> 1139<a href="https://spring.pleiades.io/spring-framework/reference/core/aop/ataspectj/pointcuts.html#aop-pointcuts-designators">AOP</a>ã使ã£ã¦ <code>@Repository</code> å ã®ã¡ã½ããã§ <code>DomainException</code> ãæããããã <code>DomainMappingException</code> ã«å¤æãã¦æãç´ããã¨ã«ãã<br/> 1140ãã¨ã¯ããããã®ä¾å¤ã«å¿ãã¦ãä¾å¤ãã³ãã©ã¼ãè¨å®ããã°ããæãã«ä½ææã¨åæ§ææã§æ¯ãèããå¤ãããã</p> 1141 1142<pre class="code lang-kotlin" data-lang="kotlin" data-unlink><span class="synIdentifier">@Aspect</span> 1143<span class="synIdentifier">@Component</span> 1144<span class="synType">class</span> RepositoryExceptionTranslator { 1145 <span class="synIdentifier">@AfterThrowing</span>(value = <span class="synConstant">"@within(org.springframework.stereotype.Repository)"</span>, throwing = <span class="synConstant">"e"</span>) 1146 <span class="synType">fun</span> translate(e: <span class="synType">Throwable</span>) { 1147 <span class="synStatement">throw</span> <span class="synStatement">when</span>(e) { 1148 <span class="synStatement">is</span> DomainException <span class="synType">-></span> DomainMappingException(e) 1149 <span class="synStatement">else</span> <span class="synType">-></span> e 1150 } 1151 } 1152} 1153</pre> 1154 1155 1156<p>ããããã¨ãã¯ãã£ã±ãAOPã便å©ã ãªã¨ãã£ãææ³<br/> 1157試ãã¦ããã½ã¼ã¹ã®ã³ã¼ãã¯â</p> 1158 1159<p><iframe src="https://hatenablog-parts.com/embed?url=https%3A%2F%2Fgithub.com%2Fatr0phy%2Fspring-aop-exception-translator" title="GitHub - atr0phy/spring-aop-exception-translator" class="embed-card embed-webcard" scrolling="no" frameborder="0" style="display: block; width: 100%; height: 155px; max-width: 500px; margin: 10px 0px;" loading="lazy"></iframe><cite class="hatena-citation"><a href="https://github.com/atr0phy/spring-aop-exception-translator">github.com</a></cite></p> 1160 1161 1162 1163 1164 1165</div> 1166 1167 1168 <footer class="entry-footer"> 1169 1170 <div class="entry-tags-wrapper"> 1171 <div class="entry-tags"> </div> 1172</div> 1173 1174 <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> 1175 <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="atr0phy" >atr0phy</span></span> 1176 <span class="entry-footer-time"><a href="https://www.hacktotech.net/entry/spring-boot-exception-translator-for-repository-annotation"><time data-relative datetime="2024-03-31T08:55:26Z" title="2024-03-31T08:55:26Z" class="updated">2024-03-31 17:55</time></a></span> 1177 1178 1179 1180</p> 1181 1182 1183 <div 1184 class="hatena-star-container" 1185 data-hatena-star-container 1186 data-hatena-star-url="https://www.hacktotech.net/entry/spring-boot-exception-translator-for-repository-annotation" 1187 data-hatena-star-title="SpringBootã§@Repositoryãã¤ããã¯ã©ã¹ã®ã¡ã½ããããæããããä¾å¤ã夿ãã¦æãç´ã" 1188 data-hatena-star-variant="profile-icon" 1189 data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" 1190 ></div> 1191 1192 1193 1194<div class="social-buttons"> 1195 1196
1197 <div class="social-button-item"> 1198 <a href="https://b.hatena.ne.jp/entry/s/www.hacktotech.net/entry/spring-boot-exception-translator-for-repository-annotation" class="hatena-bookmark-button" data-hatena-bookmark-url="https://www.hacktotech.net/entry/spring-boot-exception-translator-for-repository-annotation" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å "><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å " width="20" height="20" style="border: none;" /></a> 1199 </div> 1200 1201 1202 1203 1204 1205 <div class="social-button-item"> 1206 <a 1207 class="entry-share-button entry-share-button-twitter test-share-button-twitter" 1208 href="https://x.com/intent/tweet?text=SpringBoot%E3%81%A7%40Repository%E3%81%8C%E3%81%A4%E3%81%84%E3%81%9F%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%8B%E3%82%89%E6%8A%95%E3%81%92%E3%82%89%E3%82%8C%E3%81%9F%E4%BE%8B%E5%A4%96%E3%82%92%E5%A4%89%E6%8F%9B%E3%81%97%E3%81%A6%E6%8A%95%E3%81%92%E7%9B%B4%E3%81%99+-+HackToTech&url=https%3A%2F%2Fwww.hacktotech.net%2Fentry%2Fspring-boot-exception-translator-for-repository-annotation" 1209 title="Xï¼Twitterï¼ã§æç¨¿ãã" 1210 ></a> 1211 </div> 1212 1213 1214 1215 1216 1217 1218</div> 1219 1220 1221 1222 <div class="customized-footer"> 1223 1224 1225 </div> 1226 1227 1228 </footer> 1229 1230 </div> 1231</article> 1232 1233 1234 1235 1236 1237 1238 1239 <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-200 words-100 mode-markdown entry-odd" id="entry-6801883189078533680" data-keyword-campaign="" data-uuid="6801883189078533680" data-publication-type="entry"> 1240 <div class="entry-inner"> 1241 <header class="entry-header"> 1242 1243 <div class="date entry-date first"> 1244 <a href="https://www.hacktotech.net/archive/2024/01/28" rel="nofollow"> 1245 <time datetime="2024-01-27T15:24:48Z" title="2024-01-27T15:24:48Z"> 1246 <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">01</span><span class="hyphen">-</span><span class="date-day">28</span> 1247 </time> 1248 </a> 1249 </div> 1250 <h1 class="entry-title"> 1251 <a href="https://www.hacktotech.net/entry/select-file-by-whiptail-and-ls" class="entry-title-link bookmark">whiptailã§lsãã¦ãã¡ã¤ã«é¸æããçµæãåå¾ãã</a> 1252</h1> 1253 1254 1255 1256 1257 <div class="entry-categories categories"> 1258 1259 <a href="https://www.hacktotech.net/archive/category/whiptail" class="entry-category-link category-whiptail">whiptail</a> 1260 1261 <a href="https://www.hacktotech.net/archive/category/bash" class="entry-category-link category-bash">bash</a> 1262 1263 </div> 1264 1265 1266 1267 1268 1269 1270</header> 1271 1272 1273 1274 1275 <div class="entry-content hatenablog-entry"> 1276 1277 <p>ã¹ã¯ãªããæ¸ãã¦ãã¨ãã¾ã¼ã«æ¬²ãããªããã¤<br/> 1278æ¤ç´¢ãã¦ããªããã±ã£ã¨ããæãã®ãã¤ãåºã¦ããªãã®ã§(é·ããã¦ã³ããããã®ã«èºèºããã¤ã¨ã)ã主ã«èªåã®ãã¼ã«ã«ã§ä½¿ãããã«æ¸ãã</p> 1279
1280<script src="https://gist.github.com/atr0phy/a17fead8c0a893ba7ce435da1859a998.js"></script>
1280 1281 1282 1283<p>â㯠<code>/sbin</code> ã§è©¦ããã㤠1284<span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/atr0phy/20240128/20240128001355.png" width="1200" height="584" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span> 1285<span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/a/atr0phy/20240128/20240128001406.png" width="455" height="67" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></p> 1286 1287<p>macã§ä½¿ããªã <a href="https://formulae.brew.sh/formula/coreutils"><code>brew install coreutils</code> </a>ãã¦ã <code>gls</code> 使ããªãã¨åããªãã®ã§æ³¨æ</p> 1288 1289<p>ç¸å¤ããã <code>bash</code> 使ã£ã¦ããã©ãããå æ¸ä»ã®ã·ã§ã«ã«ããã»ããè¯ããæ©ã¾ãã</p> 1290 1291 1292 1293 1294 1295</div> 1296 1297 1298 <footer class="entry-footer"> 1299 1300 <div class="entry-tags-wrapper"> 1301 <div class="entry-tags"> </div> 1302</div> 1303 1304 <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> 1305 <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="atr0phy" >atr0phy</span></span> 1306 <span class="entry-footer-time"><a href="https://www.hacktotech.net/entry/select-file-by-whiptail-and-ls"><time data-relative datetime="2024-01-27T15:24:48Z" title="2024-01-27T15:24:48Z" class="updated">2024-01-28 00:24</time></a></span> 1307 1308 1309 1310</p> 1311 1312 1313 <div 1314 class="hatena-star-container" 1315 data-hatena-star-container 1316 data-hatena-star-url="https://www.hacktotech.net/entry/select-file-by-whiptail-and-ls" 1317 data-hatena-star-title="whiptailã§lsãã¦ãã¡ã¤ã«é¸æããçµæãåå¾ãã" 1318 data-hatena-star-variant="profile-icon" 1319 data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" 1320 ></div> 1321 1322 1323 1324<div class="social-buttons"> 1325 1326 1327 <div class="social-button-item"> 1328 <a href="https://b.hatena.ne.jp/entry/s/www.hacktotech.net/entry/select-file-by-whiptail-and-ls" class="hatena-bookmark-button" data-hatena-bookmark-url="https://www.hacktotech.net/entry/select-file-by-whiptail-and-ls" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å "><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="ãã®è¨äºãã¯ã¦ãªããã¯ãã¼ã¯ã«è¿½å " width="20" height="20" style="border: none;" /></a> 1329 </div> 1330 1331 1332 1333 1334 1335 <div class="social-button-item"> 1336 <a 1337 class="entry-share-button entry-share-button-twitter test-share-button-twitter" 1338 href="https://x.com/intent/tweet?text=whiptail%E3%81%A7ls%E3%81%97%E3%81%A6%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E9%81%B8%E6%8A%9E%E3%81%97%E3%81%9F%E7%B5%90%E6%9E%9C%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B+-+HackToTech&url=https%3A%2F%2Fwww.hacktotech.net%2Fentry%2Fselect-file-by-whiptail-and-ls" 1339 title="Xï¼Twitterï¼ã§æç¨¿ãã" 1340 ></a> 1341 </div> 1342 1343 1344 1345 1346 1347 1348</div> 1349 1350 1351 1352 <div class="customized-footer"> 1353 1354 1355 </div> 1356 1357 1358 </footer> 1359 1360 </div> 1361</article> 1362 1363 1364 1365 1366 1367 1368 1369 <!-- rakuten_ad_target_end --> 1370 <!-- google_ad_section_end --> 1371 1372 1373 1374 <div class="pager autopagerize_insert_before"> 1375 <span class="pager-next"> 1376 <a href="https://www.hacktotech.net/?page=2" rel="next">次ã®ãã¼ã¸</a> 1377 </span> 1378 </div> 1379 1380 1381 1382 1383 </div> 1384 </div> 1385 1386 <aside id="box1"> 1387 <div id="box1-inner"> 1388 </div> 1389</aside> 1390 1391 </div><!-- #wrapper --> 1392 1393 1394<aside id="box2"> 1395 1396 <div id="box2-inner"> 1397 1398 1399 1400<div class="hatena-module hatena-module-profile"> 1401 <div class="hatena-module-title"> 1402 ãããã£ã¼ã« 1403 </div> 1404 <div class="hatena-module-body"> 1405 1406 <a href="https://www.hacktotech.net/about" class="profile-icon-link"> 1407 <img src="https://cdn.profile-image.st-hatena.com/users/atr0phy/profile.png?1789619440" 1408 alt="id:atr0phy" class="profile-icon" /> 1409 </a> 1410 1411 1412 1413 1414 1415 1416 1417 <div class="profile-description"> 1418 <p>試ãããã¨ãå¦ãã ãã¨æ¸ãã¦ã¾ã</p> 1419 1420 </div> 1421 1422 1423 1424 1425 1426 1427 <div class="profile-about"> 1428 <a href="https://www.hacktotech.net/about">ãã®ããã°ã«ã¤ãã¦</a> 1429 </div> 1430 1431 </div> 1432</div> 1433 1434 1435 <div class="hatena-module hatena-module-recent-entries "> 1436 <div class="hatena-module-title"> 1437 <a href="https://www.hacktotech.net/archive"> 1438 ææ°è¨äº 1439 </a> 1440 </div> 1441 <div class="hatena-module-body"> 1442 <ul class="recent-entries hatena-urllist "> 1443 1444 1445 1446 <li class="urllist-item recent-entries-item"> 1447 <div class="urllist-item-inner recent-entries-item-inner"> 1448 1449 1450 1451 <a href="https://www.hacktotech.net/entry/mockito-kotlin-value-class" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title">mockito-kotlinã§value classããµãã¼ãããããããã®ã§ã¡ã¢</a> 1452 1453 1454 1455 1456 1457 1458 1459 </div> 1460 </li> 1461 1462 1463 <li class="urllist-item recent-entries-item"> 1464 <div class="urllist-item-inner recent-entries-item-inner"> 1465 1466 1467 1468 <a href="https://www.hacktotech.net/entry/sbom-memo" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title">
1468SBOMå¨ããè¦ã¦ãã®ã§ã¡ã¢</a> 1469 1470 1471 1472 1473 1474 1475 1476 </div> 1477 </li> 1478 1479 1480 <li class="urllist-item recent-entries-item"> 1481 <div class="urllist-item-inner recent-entries-item-inner"> 1482 1483 1484 1485 <a href="https://www.hacktotech.net/entry/use-spring-milestone-version" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title">Springã®milestoneã®ãã¼ã¸ã§ã³ã試ãã¦ãã®ã§ã¡ã¢</a> 1486 1487 1488 1489 1490 1491 1492 1493 </div> 1494 </li> 1495 1496 1497 <li class="urllist-item recent-entries-item"> 1498 <div class="urllist-item-inner recent-entries-item-inner"> 1499 1500 1501 1502 <a href="https://www.hacktotech.net/entry/spring-boot-exception-translator-for-repository-annotation" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title">SpringBootã§@Repositoryãã¤ããã¯ã©ã¹ã®ã¡ã½ããããæããããä¾å¤ã夿ãã¦æãç´ã</a> 1503 1504 1505 1506 1507 1508 1509 1510 </div> 1511 </li> 1512 1513 1514 <li class="urllist-item recent-entries-item"> 1515 <div class="urllist-item-inner recent-entries-item-inner"> 1516 1517 1518 1519 <a href="https://www.hacktotech.net/entry/select-file-by-whiptail-and-ls" class="urllist-title-link recent-entries-title-link urllist-title recent-entries-title">whiptailã§lsãã¦ãã¡ã¤ã«é¸æããçµæãåå¾ãã</a> 1520 1521 1522 1523 1524 1525 1526 1527 </div> 1528 </li> 1529 1530</ul> 1531 1532 </div> 1533</div> 1534 1535 1536 1537 1538<div class="hatena-module hatena-module-category"> 1539 <div class="hatena-module-title"> 1540 ã«ãã´ãªã¼ 1541 </div> 1542 <div class="hatena-module-body"> 1543 <ul class="hatena-urllist"> 1544 1545 <li> 1546 <a href="https://www.hacktotech.net/archive/category/aws" class="category-aws"> 1547 aws (3) 1548 </a> 1549 </li> 1550 1551 <li> 1552 <a href="https://www.hacktotech.net/archive/category/iam" class="category-iam"> 1553 iam (1) 1554 </a> 1555 </li> 1556 1557 <li> 1558 <a href="https://www.hacktotech.net/archive/category/mockito" class="category-mockito"> 1559 mockito (2) 1560 </a> 1561 </li> 1562 1563 <li> 1564 <a href="https://www.hacktotech.net/archive/category/kotlin" class="category-kotlin"> 1565 kotlin (13) 1566 </a> 1567 </li> 1568 1569 <li> 1570 <a href="https://www.hacktotech.net/archive/category/sbom" class="category-sbom"> 1571 sbom (1) 1572 </a> 1573 </li> 1574 1575 <li> 1576 <a href="https://www.hacktotech.net/archive/category/spring" class="category-spring"> 1577 spring (7) 1578 </a> 1579 </li> 1580 1581 <li> 1582 <a href="https://www.hacktotech.net/archive/category/spring-boot" class="category-spring-boot"> 1583 spring-boot (10) 1584 </a> 1585 </li> 1586 1587 <li> 1588 <a href="https://www.hacktotech.net/archive/category/bash" class="category-bash"> 1589 bash (1) 1590 </a> 1591 </li> 1592 1593 <li> 1594 <a href="https://www.hacktotech.net/archive/category/whiptail" class="category-whiptail"> 1595 whiptail (1) 1596 </a> 1597 </li> 1598 1599 <li> 1600 <a href="https://www.hacktotech.net/archive/category/PGAudit" class="category-PGAudit"> 1601 PGAudit (1) 1602 </a> 1603 </li> 1604 1605 <li> 1606 <a href="https://www.hacktotech.net/archive/category/PostgreSQL" class="category-PostgreSQL"> 1607 PostgreSQL (1) 1608 </a> 1609 </li> 1610 1611 <li> 1612 <a href="https://www.hacktotech.net/archive/category/validation" class="category-validation"> 1613 validation (3) 1614 </a> 1615 </li> 1616 1617 <li> 1618 <a href="https://www.hacktotech.net/archive/category/jvm" class="category-jvm"> 1619 jvm (1) 1620 </a> 1621 </li> 1622 1623 <li> 1624 <a href="https://www.hacktotech.net/archive/category/java" class="category-java"> 1625 java (2) 1626 </a> 1627 </li> 1628 1629 <li> 1630 <a href="https://www.hacktotech.net/archive/category/dependabot" class="category-dependabot"> 1631 dependabot (1) 1632 </a> 1633 </li> 1634 1635 <li> 1636 <a href="https://www.hacktotech.net/archive/category/gradle" class="category-gradle"> 1637 gradle (1) 1638 </a> 1639 </li> 1640 1641 <li> 1642 <a href="https://www.hacktotech.net/archive/category/spring-security" class="category-spring-security"> 1643 spring-security (1) 1644 </a> 1645 </li> 1646 1647 <li> 1648 <a href="https://www.hacktotech.net/archive/category/tomcat" class="category-tomcat"> 1649 tomcat (2) 1650 </a> 1651 </li> 1652 1653 <li> 1654 <a href="https://www.hacktotech.net/archive/category/ubuntu" class="category-ubuntu"> 1655 ubuntu (1) 1656 </a> 1657 </li> 1658 1659 <li> 1660 <a href="https://www.hacktotech.net/archive/category/atlantis" class="category-atlantis"> 1661 atlantis (1) 1662 </a> 1663 </li> 1664 1665 <li> 1666 <a href="https://www.hacktotech.net/archive/category/terraform" class="category-terraform"> 1667 terraform (2) 1668 </a> 1669 </li> 1670 1671 <li> 1672 <a href="https://www.hacktotech.net/archive/category/pgjdbc" class="category-pgjdbc"> 1673 pgjdbc (1) 1674 </a> 1675 </li> 1676 1677 <li> 1678 <a href="https://www.hacktotech.net/archive/category/semver" class="category-semver"> 1679 semver (1) 1680 </a> 1681 </li> 1682 1683 <li> 1684 <a href="https://www.hacktotech.net/archive/category/node.js" class="category-node.js"> 1685 node.js (1) 1686 </a> 1687 </li> 1688 1689 <li> 1690 <a href="https://www.hacktotech.net/archive/category/python" class="category-python"> 1691 python (1) 1692 </a> 1693 </li> 1694 1695 <li> 1696 <a href="https://www.hacktotech.net/archive/category/cdk" class="category-cdk"> 1697 cdk (2) 1698 </a> 1699 </li> 1700 1701 <li> 1702 <a href="https://www.hacktotech.net/archive/category/fargate" class="category-fargate"> 1703 fargate (1) 1704 </a> 1705 </li> 1706 1707 <li> 1708 <a href="https://www.hacktotech.net/archive/category/GC%E6%9C%AC" class="category-GCæ¬"> 1709 GCæ¬ (2) 1710 </a> 1711 </li> 1712 1713 <li> 1714 <a href="https://www.hacktotech.net/archive/category/%E8%AA%AD%E6%9B%B8%E3%83%A1%E3%83%A2" class="category-èªæ¸ã¡ã¢"> 1715 èªæ¸ã¡ã¢ (2) 1716 </a> 1717 </li> 1718 1719 <li> 1720 <a href="https://www.hacktotech.net/archive/category/batch" class="category-batch"> 1721 batch (1) 1722 </a> 1723 </li> 1724 1725 <li> 1726 <a href="https://www.hacktotech.net/archive/category/prometheus" class="category-prometheus"> 1727 prometheus (1) 1728 </a> 1729 </li> 1730 1731 <li> 1732 <a href="https://www.hacktotech.net/archive/category/bpf" class="category-bpf"> 1733 bpf (10) 1734 </a> 1735 </li> 1736 1737 </ul> 1738 </div> 1739</div> 1740 1741 1742 1743 1744<div class="hatena-module hatena-module-archive" data-archive-type="default" data-archive-url="https://www.hacktotech.net/archive"> 1745 <div class="hatena-module-title"> 1746 <a href="https://www.hacktotech.net/archive">æå¥ã¢ã¼ã«ã¤ã</a> 1747 </div> 1748 <div class="hatena-module-body"> 1749 1750 1751 <ul class="hatena-urllist"> 1752 1753 <li class="archive-module-year archive-module-year-hidden" data-year="2024"> 1754 <div class="archive-module-button">
1755 <span class="archive-module-hide-button">â¼</span> 1756 <span class="archive-module-show-button">â¶</span> 1757 </div> 1758 <a href="https://www.hacktotech.net/archive/2024" class="archive-module-year-title archive-module-year-2024"> 1759 2024 1760 </a> 1761 <ul class="archive-module-months"> 1762 1763 <li class="archive-module-month"> 1764 <a href="https://www.hacktotech.net/archive/2024/07" class="archive-module-month-title archive-module-month-2024-7"> 1765 2024 / 7 1766 </a> 1767 </li> 1768 1769 <li class="archive-module-month"> 1770 <a href="https://www.hacktotech.net/archive/2024/05" class="archive-module-month-title archive-module-month-2024-5"> 1771 2024 / 5 1772 </a> 1773 </li> 1774 1775 <li class="archive-module-month"> 1776 <a href="https://www.hacktotech.net/archive/2024/04" class="archive-module-month-title archive-module-month-2024-4"> 1777 2024 / 4 1778 </a> 1779 </li> 1780 1781 <li class="archive-module-month"> 1782 <a href="https://www.hacktotech.net/archive/2024/03" class="archive-module-month-title archive-module-month-2024-3"> 1783 2024 / 3 1784 </a> 1785 </li> 1786 1787 <li class="archive-module-month"> 1788 <a href="https://www.hacktotech.net/archive/2024/01" class="archive-module-month-title archive-module-month-2024-1"> 1789 2024 / 1 1790 </a> 1791 </li> 1792 1793 </ul> 1794 </li> 1795 1796 <li class="archive-module-year archive-module-year-hidden" data-year="2023"> 1797 <div class="archive-module-button"> 1798 <span class="archive-module-hide-button">â¼</span> 1799 <span class="archive-module-show-button">â¶</span> 1800 </div> 1801 <a href="https://www.hacktotech.net/archive/2023" class="archive-module-year-title archive-module-year-2023"> 1802 2023 1803 </a> 1804 <ul class="archive-module-months"> 1805 1806 <li class="archive-module-month"> 1807 <a href="https://www.hacktotech.net/archive/2023/12" class="archive-module-month-title archive-module-month-2023-12"> 1808 2023 / 12 1809 </a> 1810 </li> 1811 1812 <li class="archive-module-month"> 1813 <a href="https://www.hacktotech.net/archive/2023/11" class="archive-module-month-title archive-module-month-2023-11"> 1814 2023 / 11 1815 </a> 1816 </li> 1817 1818 <li class="archive-module-month"> 1819 <a href="https://www.hacktotech.net/archive/2023/10" class="archive-module-month-title archive-module-month-2023-10"> 1820 2023 / 10 1821 </a> 1822 </li> 1823 1824 <li class="archive-module-month"> 1825 <a href="https://www.hacktotech.net/archive/2023/09" class="archive-module-month-title archive-module-month-2023-9"> 1826 2023 / 9 1827 </a> 1828 </li> 1829 1830 <li class="archive-module-month"> 1831 <a href="https://www.hacktotech.net/archive/2023/08" class="archive-module-month-title archive-module-month-2023-8"> 1832 2023 / 8 1833 </a> 1834 </li> 1835 1836 <li class="archive-module-month"> 1837 <a href="https://www.hacktotech.net/archive/2023/05" class="archive-module-month-title archive-module-month-2023-5"> 1838 2023 / 5 1839 </a> 1840 </li> 1841 1842 <li class="archive-module-month"> 1843 <a href="https://www.hacktotech.net/archive/2023/04" class="archive-module-month-title archive-module-month-2023-4"> 1844 2023 / 4 1845 </a> 1846 </li> 1847 1848 <li class="archive-module-month"> 1849 <a href="https://www.hacktotech.net/archive/2023/03" class="archive-module-month-title archive-module-month-2023-3"> 1850 2023 / 3 1851 </a> 1852 </li> 1853 1854 <li class="archive-module-month"> 1855 <a href="https://www.hacktotech.net/archive/2023/02" class="archive-module-month-title archive-module-month-2023-2"> 1856 2023 / 2 1857 </a> 1858 </li> 1859 1860 <li class="archive-module-month"> 1861 <a href="https://www.hacktotech.net/archive/2023/01" class="archive-module-month-title archive-module-month-2023-1"> 1862 2023 / 1 1863 </a> 1864 </li> 1865 1866 </ul> 1867 </li> 1868 1869 <li class="archive-module-year archive-module-year-hidden" data-year="2022"> 1870 <div class="archive-module-button">
1871 <span class="archive-module-hide-button">â¼</span> 1872 <span class="archive-module-show-button">â¶</span> 1873 </div> 1874 <a href="https://www.hacktotech.net/archive/2022" class="archive-module-year-title archive-module-year-2022"> 1875 2022 1876 </a> 1877 <ul class="archive-module-months"> 1878 1879 <li class="archive-module-month"> 1880 <a href="https://www.hacktotech.net/archive/2022/12" class="archive-module-month-title archive-module-month-2022-12"> 1881 2022 / 12 1882 </a> 1883 </li> 1884 1885 <li class="archive-module-month"> 1886 <a href="https://www.hacktotech.net/archive/2022/11" class="archive-module-month-title archive-module-month-2022-11"> 1887 2022 / 11 1888 </a> 1889 </li> 1890 1891 <li class="archive-module-month"> 1892 <a href="https://www.hacktotech.net/archive/2022/07" class="archive-module-month-title archive-module-month-2022-7"> 1893 2022 / 7 1894 </a> 1895 </li> 1896 1897 <li class="archive-module-month"> 1898 <a href="https://www.hacktotech.net/archive/2022/04" class="archive-module-month-title archive-module-month-2022-4"> 1899 2022 / 4 1900 </a> 1901 </li> 1902 1903 <li class="archive-module-month"> 1904 <a href="https://www.hacktotech.net/archive/2022/03" class="archive-module-month-title archive-module-month-2022-3"> 1905 2022 / 3 1906 </a> 1907 </li> 1908 1909 <li class="archive-module-month"> 1910 <a href="https://www.hacktotech.net/archive/2022/02" class="archive-module-month-title archive-module-month-2022-2"> 1911 2022 / 2 1912 </a> 1913 </li> 1914 1915 </ul> 1916 </li> 1917 1918 <li class="archive-module-year archive-module-year-hidden" data-year="2021"> 1919 <div class="archive-module-button"> 1920 <span class="archive-module-hide-button">â¼</span> 1921 <span class="archive-module-show-button">â¶</span> 1922 </div> 1923 <a href="https://www.hacktotech.net/archive/2021" class="archive-module-year-title archive-module-year-2021"> 1924 2021 1925 </a> 1926 <ul class="archive-module-months"> 1927 1928 <li class="archive-module-month"> 1929 <a href="https://www.hacktotech.net/archive/2021/10" class="archive-module-month-title archive-module-month-2021-10"> 1930 2021 / 10 1931 </a> 1932 </li> 1933 1934 <li class="archive-module-month"> 1935 <a href="https://www.hacktotech.net/archive/2021/07" class="archive-module-month-title archive-module-month-2021-7"> 1936 2021 / 7 1937 </a> 1938 </li> 1939 1940 </ul> 1941 </li> 1942 1943 <li class="archive-module-year archive-module-year-hidden" data-year="2020"> 1944 <div class="archive-module-button"> 1945 <span class="archive-module-hide-button">â¼</span> 1946 <span class="archive-module-show-button">â¶</span> 1947 </div> 1948 <a href="https://www.hacktotech.net/archive/2020" class="archive-module-year-title archive-module-year-2020"> 1949 2020 1950 </a> 1951 <ul class="archive-module-months"> 1952 1953 <li class="archive-module-month"> 1954 <a href="https://www.hacktotech.net/archive/2020/12" class="archive-module-month-title archive-module-month-2020-12"> 1955 2020 / 12 1956 </a> 1957 </li> 1958 1959 <li class="archive-module-month"> 1960 <a href="https://www.hacktotech.net/archive/2020/11" class="archive-module-month-title archive-module-month-2020-11"> 1961 2020 / 11 1962 </a> 1963 </li> 1964 1965 <li class="archive-module-month"> 1966 <a href="https://www.hacktotech.net/archive/2020/07" class="archive-module-month-title archive-module-month-2020-7"> 1967 2020 / 7 1968 </a> 1969 </li> 1970 1971 <li class="archive-module-month"> 1972 <a href="https://www.hacktotech.net/archive/2020/04" class="archive-module-month-title archive-module-month-2020-4"> 1973 2020 / 4 1974 </a> 1975 </li> 1976 1977 <li class="archive-module-month"> 1978 <a href="https://www.hacktotech.net/archive/2020/01" class="archive-module-month-title archive-module-month-2020-1"> 1979 2020 / 1 1980 </a> 1981 </li> 1982 1983 </ul> 1984 </li> 1985 1986 <li class="archive-module-year archive-module-year-hidden" data-year="2019"> 1987 <div class="archive-module-button">
1988 <span class="archive-module-hide-button">â¼</span> 1989 <span class="archive-module-show-button">â¶</span> 1990 </div> 1991 <a href="https://www.hacktotech.net/archive/2019" class="archive-module-year-title archive-module-year-2019"> 1992 2019 1993 </a> 1994 <ul class="archive-module-months"> 1995 1996 <li class="archive-module-month"> 1997 <a href="https://www.hacktotech.net/archive/2019/12" class="archive-module-month-title archive-module-month-2019-12"> 1998 2019 / 12 1999 </a> 2000 </li> 2001 2002 </ul> 2003 </li> 2004 2005 </ul> 2006 2007 2008 </div> 2009</div> 2010 2011 2012 </div> 2013</aside> 2014 2015 2016 </div> 2017</div> 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 </div> 2028 </div> 2029 2030 2031 2032
2032<script async src="https://s.hatena.ne.jp/js/widget/star.js"></script>
2032 2033 2034 2035
2035<script> 2036 if (typeof window.Hatena === 'undefined') { 2037 window.Hatena = {}; 2038 } 2039 if (!Hatena.hasOwnProperty('Star')) { 2040 Hatena.Star = { 2041 VERSION: 2, 2042 }; 2043 } 2044 </script>
2044 2045 2046 2047 2048 2049 2050<div class="quote-box"> 2051 <div class="tooltip-quote tooltip-quote-stock"> 2052 <i class="blogicon-quote" title="å¼ç¨ãã¹ããã¯"></i> 2053 </div> 2054 <div class="tooltip-quote tooltip-quote-tweet js-tooltip-quote-tweet"> 2055 <a class="js-tweet-quote" target="_blank" data-track-name="quote-tweet" data-track-once> 2056 <img src="https://cdn.blog.st-hatena.com/images/admin/quote/quote-x-icon.svg?version=89f69427ebf1344326896140241320" title="å¼ç¨ãã¦æç¨¿ãã" > 2057 </a> 2058 </div> 2059</div> 2060 2061<div class="quote-stock-panel" id="quote-stock-message-box" style="position: absolute; z-index: 3000"> 2062 <div class="message-box" id="quote-stock-succeeded-message" style="display: none"> 2063 <p>å¼ç¨ãã¹ããã¯ãã¾ãã</p> 2064 <button class="btn btn-primary" id="quote-stock-show-editor-button" data-track-name="curation-quote-edit-button">ã¹ããã¯ä¸è¦§ãè¦ã</button> 2065 <button class="btn quote-stock-close-message-button">éãã</button> 2066 </div> 2067 2068 <div class="message-box" id="quote-login-required-message" style="display: none"> 2069 <p>å¼ç¨ããã«ã¯ã¾ããã°ã¤ã³ãã¦ãã ãã</p> 2070 <button class="btn btn-primary" id="quote-login-button">ãã°ã¤ã³</button> 2071 <button class="btn quote-stock-close-message-button">éãã</button> 2072 </div> 2073 2074 <div class="error-box" id="quote-stock-failed-message" style="display: none"> 2075 <p>å¼ç¨ãã¹ããã¯ã§ãã¾ããã§ãããå度ã試ããã ãã</p> 2076 <button class="btn quote-stock-close-message-button">éãã</button> 2077 </div> 2078 2079 <div class="error-box" id="unstockable-quote-message-box" style="display: none; position: absolute; z-index: 3000;"> 2080 <p>éå®å ¬éè¨äºã®ããå¼ç¨ã§ãã¾ããã</p> 2081 </div> 2082</div> 2083
2084<script type="x-underscore-template" id="js-requote-button-template"> 2085 <div class="requote-button js-requote-button"> 2086 <button class="requote-button-btn tipsy-top" title="å¼ç¨ãã"><i class="blogicon-quote"></i></button> 2087 </div> 2088</script>
2088 2089 2090 2091 2092 2093 <div id="hidden-subscribe-button" style="display: none;"> 2094 <div class="hatena-follow-button-box btn-subscribe js-hatena-follow-button-box" 2095 2096 > 2097 2098 <a href="#" class="hatena-follow-button js-hatena-follow-button"> 2099 <span class="subscribing"> 2100 <span class="foreground">èªè ã§ã</span> 2101 <span class="background">èªè ãããã</span> 2102 </span> 2103 <span class="unsubscribing" data-track-name="profile-widget-subscribe-button" data-track-once> 2104 <span class="foreground">èªè ã«ãªã</span> 2105 <span class="background">èªè ã«ãªã</span> 2106 </span> 2107 </a> 2108 <div class="subscription-count-box js-subscription-count-box"> 2109 <i></i> 2110 <u></u> 2111 <span class="subscription-count js-subscription-count"> 2112 </span> 2113 </div> 2114</div> 2115 2116 </div> 2117 2118 2119 2120 2121 2122 2123 2124 2125
2125<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
2125 2126
2127<script src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
2127 2128 2129
2130<script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/jquery.min.js?v=1.12.4&version=89f69427ebf1344326896140241320"></script>
2130 2131 2132 2133 2134 2135 2136 2137
2138<script src="https://cdn.blog.st-hatena.com/js/texts-ja.js?version=89f69427ebf1344326896140241320"></script>
2138 2139 2140 2141 2142
2142<script id="vendors-js" data-env="production" src="https://cdn.blog.st-hatena.com/js/vendors.js?version=89f69427ebf1344326896140241320" crossorigin="anonymous"></script>
2142 2143
2144<script id="hatenablog-js" data-env="production" src="https://cdn.blog.st-hatena.com/js/hatenablog.js?version=89f69427ebf1344326896140241320" crossorigin="anonymous" data-page-id="index"></script>
2144 2145 2146 2147
2147<script>Hatena.Diary.GlobalHeader.init()</script>
2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 </body> 2164</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.