PageSourceSearch

https://armeria.dev/assets/js/91dc6ab4.5e385f59.js

js armeria.dev collected 2026-10-03 23:26:02 UTC 25,722 bytes, 24 lines download raw bytes

1"use strict";(self.webpackChunkarmeria_site=self.webpackChunkarmeria_site||[]).push([["5316"],{62277(e,r,o){o.r(r),o.d(r,{metadata:()=>t,default:()=>m,frontMatter:()=>n,contentTitle:()=>c,toc:()=>p,assets:()=>l});var t=JSON.parse('{"id":"tutorials/grpc/index","title":"gRPC tutorial introduction","description":"In this tutorial, you\'ll learn how to build a gRPC service with Armeria.","source":"@site/src/content/docs/tutorials/grpc/index.mdx","sourceDirName":"tutorials/grpc","slug":"/tutorials/grpc/","permalink":"/docs/tutorials/grpc/","draft":false,"unlisted":false,"editUrl":"https://github.com/line/armeria/edit/main/site/src/content/docs/tutorials/grpc/index.mdx","tags":[],"version":"current","frontMatter":{"type":"tutorial","level":"basic"},"sidebar":"docsSidebar","previous":{"title":"7. Implement DELETE","permalink":"/docs/tutorials/rest/implement-delete"},"next":{"title":"1. Define a service","permalink":"/docs/tutorials/grpc/define-service"}}'),i=o(74848),a=o(28453),s=o(12793);let n={type:"tutorial",level:"basic"},c="gRPC tutorial introduction",l={},p=[{value:"Background",id:"background",level:2},{value:"Assumptions",id:"assumptions",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Sample service",id:"sample-service",level:2},{value:"Build and run sample service",id:"build-and-run-sample-service",level:2},{value:"Try writing blog service yourself",id:"try-writing-blog-service-yourself",level:2}];function g(e){let r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components},{CodeBlock:o}=r;return o||function(e,r){throw Error("Expected "+(r?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}("CodeBlock",!0),(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(r.header,{children:(0,i.jsx)(r.h1,{id:"grpc-tutorial-introduction",children:"gRPC tutorial introduction"})}),"\n",(0,i.jsxs)(r.p,{children:["In this tutorial, you'll learn how to build a ",(0,i.jsx)(r.a,{href:"https://grpc.io/",children:"gRPC"})," service with Armeria.\nThis tutorial is based on a ",(0,i.jsx)(r.a,{href:"#sample-service",children:"sample service"}),", a minimal blog service, with which you can create, read, update, and delete blog posts."]}),"\n",(0,i.jsxs)(r.p,{children:["Follow this tutorial to write a service yourself or try ",(0,i.jsx)(r.a,{href:"#build-and-run-sample-service",children:"running the sample service"})," right away."]}
1),"\n",(0,i.jsx)(r.h2,{id:"background",children:"Background"}),"\n",(0,i.jsx)(r.p,{children:"Before we get our hands on the tutorial, let's swiftly go over Armeria's gRPC features.\nArmeria supports features that the upstream (gRPC-Java) does not support."}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsxs)(r.li,{children:["Protocol","\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsx)(r.li,{children:"HTTP/1.1"}),"\n",(0,i.jsx)(r.li,{children:"HTTP/2 (upstream)"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["Serialization format - Framed","\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsx)(r.li,{children:"gRPC protobuf: application/grpc+proto (upstream)"}),"\n",(0,i.jsx)(r.li,{children:"gRPC JSON: application/grpc+json"}),"\n",(0,i.jsx)(r.li,{children:"gRPC Web: application/grpc-web+proto"}),"\n",(0,i.jsx)(r.li,{children:"gRPC Web JSON: application/grpc-web+json"}),"\n",(0,i.jsx)(r.li,{children:"gRPC Web Text: application/grpc-web-text+proto"}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(r.li,{children:["Serialization format - Unframed","\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsx)(r.li,{children:"Protobuf: application/protobuf"}),"\n",(0,i.jsx)(r.li,{children:"JSON: application/json"}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/server/grpc#decorating-a-grpcservice",children:"HTTP level decorator"})}),"\n",(0,i.jsx)(r.li,{children:"Richer error handling"}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"https://google.aip.dev/127",children:"HTTP-to-JSON transcoding"})}),"\n",(0,i.jsx)(r.li,{children:"Customizing service method paths"}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/server/docservice",children:"gRPC documentation service"})}),"\n",(0,i.jsxs)(r.li,{children:["gRPC status monitoring with ",(0,i.jsx)(r.a,{href:"type://https://javadoc.io/doc/com.linecorp.armeria/armeria-javadoc/latest/com/linecorp/armeria/server/metric/MetricCollectingService.html",children:"MetricCollectingService"})]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"assumptions",children:"Assumptions"}),"\n",(0,i.jsx)(r.p,{children:"This tutorial assumes that you have:"}),"\n",(0,i.jsxs)(r.ul,{children:["\n",(0,i.jsx)(r.li,{children:"Experience in building services in Java"}),"\n",(0,i.jsx)(r.li,{children:"Experience in Java frameworks for server-side programming"}),"\n",(0,i.jsx)(r.li,{children:"Understanding of gRPC and experience in implementing gRPC services"}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsx)(r.p,{children:"To run and develop the sample service, you need JDK 11 or higher."}),"\n",(0,i.jsx)(r.h2,{id:"sample-service",children:"Sample service"}),"\n",(0,i.jsxs)(r.p,{children:["The ",(0,i.jsx)(r.a,{href:"https://github.com/line/armeria-examples/tree/main/tutorials/grpc",children:"sample service"})," provides implementations of CRUD operations as specified below."]}),"\n",(0,i.jsxs)(r.table,{children:[(0,i.jsx)(r.thead,{children:(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.th,{children:"Operation"}),(0,i.jsx)(r.th,{children:"Method"})]})}),(0,i.jsxs)(r.tbody,{children:[(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"Create"}),(0,i.jsx)(r.td,{children:(0,i.jsx)(r.code,{children:"createBlogPost()"})})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"Read"}),(0,i.jsxs)(r.td,{children:[(0,i.jsx)(r.code,{children:"getBlogPost()"}),", ",(0,i.jsx)(r.code,{children:"listBlogPosts()"})]})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"Update"}),(0,i.jsx)(r.td,{children:(0,i.jsx)(r.code,{children:"updateBlogPost()"})})]}),(0,i.jsxs)(r.tr,{children:[(0,i.jsx)(r.td,{children:"Delete"}),(0,i.jsx)(r.td,{children:(0,i.jsx)(r.code,{children:"deleteBlogPost()"})})]})]})]}),"\n",(0,i.jsx)(r.p,{children:"The sample service code consists of the following folders and files."}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{children:"grpc/\n\u251C\u2500 src/\n\u2502  \u251C\u2500 main/\n\u2502  \u2502  \u251C\u2500 java/\n\u2502  \u2502  \u2502  \u251C\u2500 example.armeria.server.blog.grpc/\n\u2502  \u2502  \u2502  \u2502  \u251C\u2500 BlogNotFoundException.java\n\u2502  \u2502  \u2502  \u2502  \u251C\u2500 BlogService.java\n\u2502  \u2502  \u2502  \u2502  \u251C\u2500 GrpcExceptionHandler.java\n\u2502  \u2502  \u2502  \u2502  \u2514\u2500 Main.java\n\u2502  \u2502  \u251C\u2500 proto/\n\u2502  \u2502  \u2502  \u2514\u2500 blog.proto\n\u2502  \u2514\u2500 test/\n\u2502     \u2514\u2500 java/\n\u2502        \u2514\u2500 example.armeria.server.blog.grpc/\n\u2502           \u2514\u2500 BlogServiceTest.java\n\u2514\u2500 build.gradle\n"})}),"\n",(0,i.jsx)(r.admonition,{type:"tip",children:(0,i.jsx)(r.p,{children:"To keep our focus on Armeria, this tutorial and the sample service implement memory-based operations instead of using a database."})}),"\n",(0,i.jsx)(r.h2,{id:"build-and-run-sample-service",children:"Build and run sample service"}),"\n",(0,i.jsxs)(r.p,{children:["The sample service provides you implementations of C
1RUD operations with corresponding service methods.\nHave a go at running the sample gRPC service and see the outcome of this tutorial.\nUsing Armeria's ",(0,i.jsx)(r.a,{href:"/docs/server/docservice",children:"Documentation Service"}),", you can easily verify a server is running, receiving requests and sending responses."]}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsxs)(r.li,{children:["Download the code from ",(0,i.jsx)(r.a,{href:"https://github.com/line/armeria-examples/tree/main/tutorials/grpc",children:"here"}),"."]}),"\n",(0,i.jsx)(r.li,{children:"Build the sample service using the Gradle Wrapper."}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"$ ./gradlew build\n"})}),"\n",(0,i.jsxs)(r.ol,{start:"3",children:["\n",(0,i.jsx)(r.li,{children:"Run the sample service again, using the Gradle Wrapper."}),"\n"]}),"\n",(0,i.jsx)(r.pre,{children:(0,i.jsx)(r.code,{className:"language-bash",children:"$ ./gradlew run\n"})}),"\n",(0,i.jsxs)(r.ol,{start:"4",children:["\n",(0,i.jsxs)(r.li,{children:["Open the Documentation service page on your web browser at ",(0,i.jsx)(r.a,{href:"http://127.0.0.1:8080/docs",children:"http://127.0.0.1:8080/docs"}),"."]}),"\n"]}),"\n",(0,i.jsx)(r.h2,{id:"try-writing-blog-service-yourself",children:"Try writing blog service yourself"}),"\n",(0,i.jsxs)(r.p,{children:["Use the sample service's ",(0,i.jsx)(r.a,{href:"https://github.com/line/armeria-examples/blob/main/tutorials/grpc/build.gradle",children:"build.gradle"})," file to start building the service from scratch.\nBelow is a part of the ",(0,i.jsx)(r.code,{children:"build.gradle"})," file for the sample service.\nThis tutorial uses ",(0,i.jsx)(r.a,{href:"https://github.com/google/protobuf-gradle-plugin",children:"protobuf-gradle-plugin"})," to generate stubs from ",(0,i.jsx)(r.code,{children:"proto"})," files."]}),"\n",(0,i.jsx)(o,{language:"groovy",filename:"build.gradle",children:`
2apply plugin: 'java'
3apply plugin: 'idea'
4apply plugin: 'eclipse'
5
6repositories {
7mavenCentral()
8}
9
10dependencies {
11implementation "com.linecorp.armeria:armeria:${s["com.linecorp.armeria:armeria-bom"]}"
12
13implementation "com.linecorp.armeria:armeria-grpc:${s["com.linecorp.armeria:armeria-bom"]}"
14
15// Logging
16runtimeOnly "ch.qos.logback:logback-classic:${s["ch.qos.logback:logback-classic"]}"
17
18testImplementation "org.junit.jupiter:junit-jupiter:${s["org.junit:junit-bom"]}"
19
20testImplementation "com.linecorp.armeria:armeria-junit5:${s["com.linecorp.armeria:armeria-bom"]}"
21
22testImplementation "org.assertj:assertj-core:${s["org.assertj:assertj-core"]}"
23}
24`}),"\n",(0,i.jsx)(r.p,{children:"Start writing the blog service yourself by following the tutorial step by step:"}),"\n",(0,i.jsxs)(r.ol,{children:["\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/tutorials/grpc/define-service",children:"Define a service"})}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/tutorials/grpc/run-service",children:"Run a service"})}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/tutorials/grpc/implement-create",children:"Implement CREATE"})}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/tutorials/grpc/implement-read",children:"Implement READ"})}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/tutorials/grpc/implement-update",children:"Implement UPDATE"})}),"\n",(0,i.jsx)(r.li,{children:(0,i.jsx)(r.a,{href:"/docs/tutorials/grpc/implement-delete",children:"Implement DELETE"})}),"\n"]})]})}function m(e={}){let{wrapper:r}={...(0,a.R)(),...e.components};return r?(0,i.jsx)(r,{...e,children:(0,i.jsx)(g,{...e})}):g(e)}},28453(e,r,o){o.d(r,{R:()=>s,x:()=>n});var t=o(96540);let i={},a=t.createContext(i);function s(e){let r=t.useContext(a);return t.useMemo(function(){return"function"==typeof e?e(r):{...r,...e}},[r,e])}function n(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(a.Provider,{value:r},e.children)}},12793(e){e.exports=JSON.parse('{"build.buf.protoc-gen-validate:pgv-java-stub":"1.3.3","build.buf.protoc-gen-validate:protoc-gen-validate":"1.3.3","cglib:cglib":"3.3.0","ch.megard:akka-http-cors_2.13":"1.0.0","ch.qos.logback:logback-classic":"1.5.38","com.aayushatharva.brotli4j:brotli4j":"1.23.0","com.aayushatharva.brotli4j:native-linux-aarch64":"1.23.0","com.aayushatharva.brotli4j:native-linux-x86_64":"1.23.0","com.aayushatharva.brotli4j:native-osx-aarch64":"1.23.0","com.aayushatharva.brotli4j:native-osx-x86_64":"1.23.0","com.aayushatharva.brotli4j:native-windows-x86_64":"1.23.0","com.auth0:java-jwt":"4.6.0","com.expediagroup:graphql-kotlin-client":"9.2.1","com.expediagroup:graphql-kotlin-client-jackson":"9.2.1","com.expediagroup:graphql-kotlin-client-serialization":"9.2.1","com.expediagroup:graphql-kotlin-schema-generator":"9.2.1","com.fasterxml.jackson.core:jackson-annotations":"","com.fasterxml.jackson.core:jackson-core":"","com.fasterxml.jackson.core:jackson-databind":"","com.fasterxml.jackson.dataformat:jackson-dataformat-yaml":"","com.fasterxml.jackson.datatype:jackson-datatype-jdk8":"","com.fasterxml.jackson.datatype:jackson-datatype-jsr310":"","com.fasterxml.jackson.module:jackson-module-kotlin":"","com.fasterxml.jackson.module:jackson-module-parameter-names":"","com.fasterxml.jackson.module:jackson-module-scala_2.12":"","com.fasterxml.jackson.module:jackson-module-scala_2.13":"","com.fasterxml.jackson.module:jackson-module-scala_3":"","com.fasterxml.jackson:jackson-bom":"2.22.1","com.github.ben-manes.caffeine:caffeine":"2.9.3","com.github.vladimir-bukhtoyarov:bucket4j-core":"7.6.0","com.google.api:gax-grpc":"2.72.2","com.google.code.findbugs:jsr305":"3.0.2","com.google.dagger:dagger":"2.60.1","com.google.dagger:dagger-compiler":"2.60.1","com.google.dagger:dagger-producers":"2.60.1","com.google.errorprone:error_prone_annotations":"2.50.0","com.google.errorprone:error_prone_core":"2.50.0","com.google.guava:failureaccess":"1.0.1","com.google.guava:guava":"33.6.0-jre","com.google.guava:guava-testlib":"33.6.0-jre","com.google.j2objc:j2objc-annotations":"3.1","com.google.protobuf:protobuf-bom":"4.35.1","com.google.protobuf:protobuf-gradle-plugin":"0.9.6","com.google.protobuf:protobuf-java":"3.25.9","com.google.protobuf:protobuf-java-util":"3.25.9","com.google.protobuf:protoc":"3.25.9","com.google.re2j:re2j":"1.8","com.gradleup.shadow:com.gradleup.shadow.gradle.plugin":"8.3.11","com.graphql-java:graphql-java":"26.0","com.guardsquare:proguard-gradle":"7.9.1","com.jayway.jsonpath:json-path":"3.0.0","com.lightbend.akka.grpc:akka-grpc-runtime_2.13":"1.0.3","com.linecorp.armeria:armeria-bom":"1.41.1","com.netflix.eureka:eureka-client":"2.0.6","com.netflix.eureka:eureka-test-utils":"2.0.6","com.netflix.graphql.dgs:graphql-dgs-client":"12.0.1","com.puppycrawl.tools:checkstyle":"10.3.2","com.salesforce.servicelibs:reactor-grpc":"1.2.4","com.salesforce.servicelibs:reactor-grpc-stub":"1.2.4","com.spotify:completable-futures":"0.3.6","com.spotify:futures-extra":"4.3.3","com.squareup.okhttp3:okhttp":"5.4.0","com.squareup.okhttp3:okhttp-tls":"5.4.0","com.squareup.okhttp:okhttp":"2.7.5","com.squareup.retrofit2:converter-jackson":"2.12.0","com.squareup.retrofit2:retrofit":"2.12.0","com.thesamet.scalapb:scalapb-json4s_2.12":"0.12.2","com.thesamet.scalapb:scalapb-json4s_2.13":"0.12.2","com.thesamet.scalapb:scalapb-json4s_3":"0.12.2","com.thesamet.scalapb:scalapb-runtime-grpc_2.12":"0.11.20","com.thesamet.scalapb:scalapb-runtime-grpc_2.13":"0.11.20","com.thesamet.scalapb:scalapb-runtime-grpc_3":"0.11.20","com.thesamet.scalapb:scalapb-runtime_2.12":"0.11.20","com.thesamet.scalapb:scalapb-runtime_2.13":"0.11.20","com.thesamet.scalapb:scalapb-runtime_3":"0.11.20","com.twitter:finagle-serversets_2.13":"24.2.0","com.typesafe.akka:akka-actor-typed_2.13":"2.8.8","com.typesafe.akka:akka-discovery_2.13":"2.8.8","com.typesafe.akka:akka-stream_2.13":"2.8.8","com.uber.nullaway:nullaway":"0.13.8","com.yahoo.athenz:athenz-zms-java-client":"1.12.44","com.yahoo.athenz:athenz-zpe-java-client":"1.12.44","com.yahoo.athenz:athenz-zts-java-client":"1.12.44","info.picocli:picocli":"4.7.7","io.dropwizard.metrics:metrics-bom":"4.2.39","io.dropwizard.metrics:metrics-core":"","io.dropwizard.metrics:metrics-json":"","
24io.dropwizard:dropwizard-core":"2.1.12","io.dropwizard:dropwizard-jackson":"2.1.12","io.dropwizard:dropwizard-jersey":"2.1.12","io.dropwizard:dropwizard-jetty":"2.1.12","io.dropwizard:dropwizard-lifecycle":"2.1.12","io.dropwizard:dropwizard-testing":"2.1.12","io.dropwizard:dropwizard-util":"2.1.12","io.dropwizard:dropwizard-validation":"2.1.12","io.envoyproxy.controlplane:cache":"1.0.55","io.envoyproxy.controlplane:server":"1.0.55","io.fabric8:kubernetes-client":"7.7.0","io.fabric8:kubernetes-client-api":"7.7.0","io.fabric8:kubernetes-junit-jupiter":"7.7.0","io.fabric8:kubernetes-server-mock":"7.7.0","io.github.mscheong01:krotoDC-core":"1.2.2","io.github.mscheong01:protoc-gen-krotoDC":"1.2.2","io.github.resilience4j:resilience4j-circuitbreaker":"2.4.0","io.github.resilience4j:resilience4j-micrometer":"2.4.0","io.github.resilience4j:resilience4j-spring-boot4":"2.4.0","io.grpc:grpc-bom":"1.83.0","io.grpc:grpc-core":"","io.grpc:grpc-interop-testing":"","io.grpc:grpc-kotlin-stub":"1.4.3","io.grpc:grpc-netty-shaded":"","io.grpc:grpc-okhttp":"","io.grpc:grpc-protobuf":"","io.grpc:grpc-services":"","io.grpc:grpc-stub":"","io.grpc:grpc-testing":"","io.grpc:protoc-gen-grpc-kotlin":"1.4.3","io.micrometer:context-propagation":"1.2.1","io.micrometer:micrometer-core":"1.17.0","io.micrometer:micrometer-docs-generator":"1.0.4","io.micrometer:micrometer-observation":"1.17.0","io.micrometer:micrometer-observation-test":"1.17.0","io.micrometer:micrometer-registry-prometheus":"1.17.0","io.micrometer:micrometer-registry-prometheus-simpleclient":"1.17.0","io.micrometer:micrometer-spring-legacy":"1.17.0","io.micrometer:micrometer-tracing-integration-test":"1.7.0","io.modelcontextprotocol.sdk:mcp":"","io.modelcontextprotocol.sdk:mcp-bom":"2.0.0","io.modelcontextprotocol.sdk:mcp-test":"","io.monix:monix-reactive_2.12":"3.4.1","io.monix:monix-reactive_2.13":"3.4.1","io.monix:monix-reactive_3":"3.4.1","io.netty:netty-bom":"4.2.16.Final","io.netty:netty-codec-haproxy":"","io.netty:netty-codec-http2":"","io.netty:netty-common":"","io.netty:netty-handler-proxy":"","io.netty:netty-resolver-dns":"","io.netty:netty-resolver-dns-native-macos":"","io.netty:netty-tcnative-boringssl-static":"","io.netty:netty-transport":"","io.netty:netty-transport-native-epoll":"","io.netty:netty-transport-native-io_uring":"","io.netty:netty-transport-native-kqueue":"","io.netty:netty-transport-native-unix-common":"","io.projectreactor.kotlin:reactor-kotlin-extensions":"1.3.1","io.projectreactor.tools:blockhound":"1.0.17.RELEASE","io.projectreactor.tools:blockhound-junit-platform":"1.0.17.RELEASE","io.projectreactor:reactor-core":"3.8.6","io.projectreactor:reactor-test":"3.8.6","io.prometheus:prometheus-metrics-exposition-formats":"1.8.0","io.prometheus:simpleclient_common":"0.16.0","io.reactivex.rxjava2:rxjava":"2.2.21","io.reactivex.rxjava3:rxjava":"3.1.12","io.zipkin.brave:brave":"6.3.1","io.zipkin.brave:brave-context-slf4j":"6.3.1","io.zipkin.brave:brave-instrumentation-http":"6.3.1","io.zipkin.brave:brave-instrumentation-http-tests":"6.3.1","io.zipkin.brave:brave-instrumentation-rpc":"6.3.1","it.unimi.dsi:fastutil":"8.5.19","jakarta.inject:jakarta.inject-api":"2.0.1","jakarta.validation:jakarta.validation-api":"3.1.1","jakarta.websocket:jakarta.websocket-api":"2.2.0","jakarta.websocket:jakarta.websocket-client-api":"2.2.0","javax.annotation:javax.annotation-api":"1.3.2","javax.inject:javax.inject":"1","javax.validation:validation-api":"2.0.1.Final","javax.ws.rs:jsr311-api":"1.1.1","junit:junit":"4.13.2","net.javacrumbs.json-unit:json-unit":"2.40.1","net.javacrumbs.json-unit:json-unit-fluent":"2.40.1","net.shibboleth.utilities:java-support":"7.5.2","org.apache.curator:curator-recipes":"5.9.0","org.apache.curator:curator-x-discovery":"5.9.0","org.apache.hbase:hbase-shaded-client":"1.2.6","org.apache.httpcomponents.client5:httpclient5":"5.6.2","org.apache.httpcomponents:httpclient":"4.5.14","org.apache.kafka:kafka-clients":"3.9.2","org.apache.thrift:libthrift":"0.9.3-1","org.apache.tomcat.embed:tomcat-embed-core":"9.0.120","org.apache.tomcat.embed:tomcat-embed-el":"9.0.120","org.apache.tomcat.embed:tomcat-embed-jasper":"9.0.120","org.apache.zookeeper:zookeeper":"3.9.4","org.assertj:assertj-core":"3.27.7","org.awaitility:awaitility":"4.3.0","org.bouncycastle:bcpkix-jdk18on":"1.85","org.bouncycastle:bcprov-jdk18on":"1.85","org.bouncycastle:bcutil-jdk18on":"1.85","org.checkerframework:checker-compat-qual":"2.5.6","org.curioswitch.curiostack:protobuf-jackson":"2.8.1","org.dmonix.junit:zookeeper-junit":"1.2","org.eclipse.jetty.alpn:alpn-api":"1.1.3.v20160715","org.eclipse.jetty.ee10:jetty-ee10-annotations":"12.0.37","org.eclipse.jetty.ee10:jetty-ee10-apache-jsp":"
2412.0.37","org.eclipse.jetty.ee10:jetty-ee10-glassfish-jstl":"12.0.37","org.eclipse.jetty.ee10:jetty-ee10-servlet":"12.0.37","org.eclipse.jetty.ee10:jetty-ee10-webapp":"12.0.37","org.eclipse.jetty.http2:http2-server":"9.4.58.v20250814","org.eclipse.jetty.websocket:websocket-jakarta-server":"11.0.26","org.eclipse.jetty:apache-jsp":"9.4.58.v20250814","org.eclipse.jetty:apache-jstl":"9.4.58.v20250814","org.eclipse.jetty:jetty-annotations":"9.4.58.v20250814","org.eclipse.jetty:jetty-server":"9.4.58.v20250814","org.eclipse.jetty:jetty-webapp":"9.4.58.v20250814","org.hamcrest:hamcrest":"3.0","org.hamcrest:hamcrest-library":"3.0","org.hibernate.validator:hibernate-validator":"8.0.5.Final","org.java-websocket:Java-WebSocket":"1.6.0","org.javassist:javassist":"3.32.0-GA","org.jboss.logging:jboss-logging":"3.4.3.Final","org.jboss.logging:jboss-logging-annotations":"2.2.2.Final","org.jboss.resteasy:resteasy-client":"5.0.10.Final","org.jboss.resteasy:resteasy-core":"5.0.10.Final","org.jboss.resteasy:resteasy-core-spi":"5.0.10.Final","org.jboss.resteasy:resteasy-jackson2-provider":"5.0.10.Final","org.jctools:jctools-core":"4.0.6","org.jetbrains.kotlin:kotlin-allopen":"2.4.10","org.jetbrains.kotlin:kotlin-reflect":"2.4.10","org.jetbrains.kotlin:kotlin-stdlib-jdk8":"2.4.10","org.jetbrains.kotlinx:kotlinx-coroutines-core":"1.11.0","org.jetbrains.kotlinx:kotlinx-coroutines-debug":"1.11.0","org.jetbrains.kotlinx:kotlinx-coroutines-jdk8":"1.11.0","org.jetbrains.kotlinx:kotlinx-coroutines-reactor":"1.11.0","org.jetbrains.kotlinx:kotlinx-coroutines-rx2":"1.11.0","org.jetbrains.kotlinx:kotlinx-coroutines-test":"1.11.0","org.jooq:joor":"0.9.15","org.jsoup:jsoup":"1.22.2","org.jspecify:jspecify":"1.0.0","org.junit-pioneer:junit-pioneer":"1.9.1","org.junit.jupiter:junit-jupiter-api":"","org.junit.jupiter:junit-jupiter-engine":"","org.junit.jupiter:junit-jupiter-params":"","org.junit.platform:junit-platform-commons":"","org.junit.platform:junit-platform-launcher":"","org.junit.support:testng-engine":"1.1.0","org.junit.vintage:junit-vintage-engine":"","org.junit:junit-bom":"5.14.4","org.mockito:mockito-core":"4.11.0","org.mockito:mockito-junit-jupiter":"4.11.0","org.opensaml:opensaml-core":"3.4.6","org.opensaml:opensaml-messaging-api":"3.4.6","org.opensaml:opensaml-messaging-impl":"3.4.6","org.opensaml:opensaml-saml-api":"3.4.6","org.opensaml:opensaml-saml-impl":"3.4.6","org.opensaml:opensaml-soap-api":"3.4.6","org.opensaml:opensaml-soap-impl":"3.4.6","org.ow2.asm:asm":"9.10.1","org.reactivestreams:reactive-streams":"1.0.4","org.reactivestreams:reactive-streams-tck":"1.0.4","org.reflections:reflections":"0.9.11","org.sangria-graphql:sangria-slowlog_2.12":"3.0.0","org.sangria-graphql:sangria-slowlog_2.13":"3.0.0","org.sangria-graphql:sangria_2.12":"4.2.19","org.sangria-graphql:sangria_2.13":"4.2.19","org.scala-lang.modules:scala-collection-compat_2.12":"2.14.0","org.scala-lang.modules:scala-java8-compat_2.12":"1.0.2","org.scala-lang.modules:scala-java8-compat_2.13":"1.0.2","org.scala-lang.modules:scala-java8-compat_3":"1.0.2","org.scala-lang:scala-library":"2.13.18","org.scala-lang:scala3-library_3":"3.7.4","org.scalameta:munit_2.12":"1.3.4","org.scalameta:munit_2.13":"1.3.4","org.scalameta:munit_3":"1.3.4","org.slf4j:jcl-over-slf4j":"1.7.36","org.slf4j:jul-to-slf4j":"1.7.36","org.slf4j:log4j-over-slf4j":"1.7.36","org.slf4j:slf4j-api":"2.0.18","org.slf4j:slf4j-simple":"1.7.36","org.springframework.ai:mcp-spring-webflux":"2.0.0","org.springframework.boot:spring-boot-actuator-autoconfigure":"4.1.0","org.springframework.boot:spring-boot-autoconfigure":"4.1.0","org.springframework.boot:spring-boot-configuration-processor":"4.1.0","org.springframework.boot:spring-boot-health":"4.1.0","org.springframework.boot:spring-boot-jetty":"4.1.0","org.springframework.boot:spring-boot-micrometer-metrics-test":"4.1.0","org.springframework.boot:spring-boot-micrometer-observation":"4.1.0","org.springframework.boot:spring-boot-starter":"4.1.0","org.springframework.boot:spring-boot-starter-actuator":"4.1.0","org.springframework.boot:spring-boot-starter-jetty":"4.1.0","org.springframework.boot:spring-boot-starter-security":"4.1.0","org.springframework.boot:spring-boot-starter-test":"4.1.0","org.springframework.boot:spring-boot-starter-web":"3.5.16","org.springframework.boot:spring-boot-starter-webflux":"4.1.0","org.springframework.boot:spring-boot-starter-webmvc":"4.1.0","org.springframework.boot:spring-boot-tomcat":"4.1.0","org.springframework.boot:spring-boot-validation":"4.1.0","org.springframework.boot:spring-boot-web-server":"4.1.0","org.springframework.boot:spring-boot-webclient":"4.1.0","org.springframework.boot:spring-boot-webflux-test":"4.1.0","org.springframework.boot:spring-boot-webmvc-test":"4.1.0","org.springframework:spring-aspects":"7.0.8","org.springframework:spring-context":"7.0.8","org.springframework:spring-test":"7.0.8","org.springframework:spring-web":"7.0.8","org.springframework:spring-webflux":"7.0.8","org.testcontainers:testcontainers":"","org.testcontainers:testcontainers-bom":"2.0.5","org.testcontainers:testcontainers-consul":"","org.testcontainers:testcontainers-junit-jupiter":"","org.testcontainers:testcontainers-k3s":"","org.xerial.snappy:snappy-java":"1.1.10.8","xml-apis:xml-apis":"1.4.01"}')}}]);

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.