Hi, Had a quick look at your example: https://github.com/javac9/tomee-with-jwt-demo
You shouldn’t bundle the API’s in your web app. In TomEE, these libs are shipped with the container, i.e should be in compileOnly scope: implementation("org.apache.tomee:jakartaee-api:10.0") implementation("org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:2.1“) If you change that and do a full WAR rebuild, the web app will deploy: tomee | 11-Jul-2025 18:00:33.859 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints REST Application: http://localhost:8080/demoapp/api -> com.example.tomeewithjwtdemo.HelloApplication@5fd8302e tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints Service URI: http://localhost:8080/demoapp/api/health -> Pojo org.apache.tomee.microprofile.health.MicroProfileHealthChecksEndpoint tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demoapp/api/health -> Response getChecks() tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demoapp/api/health/live -> Response getLiveChecks() tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demoapp/api/health/ready -> Response getReadyChecks() tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demoapp/api/health/started -> Response getStartedChecks() tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints Service URI: http://localhost:8080/demoapp/api/v1 -> Pojo com.example.tomeewithjwtdemo.HelloResource tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demoapp/api/v1/admin -> String helloAdmin() tomee | 11-Jul-2025 18:00:33.862 INFO [main] org.apache.openejb.server.cxf.rs.CxfRsHttpListener.logEndpoints GET http://localhost:8080/demoapp/api/v1/user -> String hello() tomee | 11-Jul-2025 18:00:33.880 INFO [main] java.lang.reflect.Method.invoke Deployment of web application archive [/usr/local/tomee/webapps/demoapp.war] has finished in [1,420] ms Since I don’t have a key cloak setup available, it will subsequently fail ;-) Gruß Richard > Am 11.07.2025 um 14:54 schrieb Java Entwicklung <javac.ay...@gmail.com>: > > ``` > # Tested with: > tomee docker image: tomee:plus > org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:2.1 > > # but same is with: > tomee docker image: tomee:10.1-jre21-plus > org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:2.2-RC1 > ``` > > Hello, > > I created a demo Jakarta EE 10 app and configured it so it authenticates > incoming requests to my protected resource against my Keycloak instance. > > It works successfully with Payara Micro 6 but with TomEE 10.0 (which is > what I need and have to use) it fails on startup with the following: > ``` > 11-Jul-2025 11:55:42.801 WARNING [main] > org.apache.batchee.container.services.ServicesManager.init You didn't > specify org.apache.batchee.jmx.application and JMX is already registered, > skipping > 2025-07-11T11:55:42.804794711Z 11-Jul-2025 11:55:42.804 INFO [main] > org.apache.openejb.assembler.classic.Assembler.createApplication Deployed > Application(path=/usr/local/tomee/webapps/demoapp) > 2025-07-11T11:55:43.426149580Z 11-Jul-2025 11:55:43.425 INFO [main] > org.apache.myfaces.webapp.MyFacesContainerInitializer.onStartup Using > org.apache.myfaces.webapp.MyFacesContainerInitializer > 2025-07-11T11:55:43.614818412Z 11-Jul-2025 11:55:43.614 INFO [main] > org.apache.myfaces.webapp.MyFacesContainerInitializer.onStartup Added > FacesServlet with mappings=[/faces/*, *.jsf, *.faces, *.xhtml] > 2025-07-11T11:55:43.628173897Z 11-Jul-2025 11:55:43.626 SEVERE [main] > java.lang.reflect.Method.invoke Error deploying web application archive > [/usr/local/tomee/webapps/demoapp.war] > 2025-07-11T11:55:43.628209564Z java.lang.IllegalStateException: Error > starting child > 2025-07-11T11:55:43.628212292Z at > org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:602) > 2025-07-11T11:55:43.628214272Z at > org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:571) > 2025-07-11T11:55:43.628215708Z at > org.apache.catalina.core.StandardHost.addChild(StandardHost.java:654) > 2025-07-11T11:55:43.628217070Z at > org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:965) > 2025-07-11T11:55:43.628218545Z at > org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1903) > 2025-07-11T11:55:43.628219991Z at > java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown > Source) > 2025-07-11T11:55:43.628221298Z at > java.base/java.util.concurrent.FutureTask.run(Unknown Source) > 2025-07-11T11:55:43.628222601Z at > org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) > 2025-07-11T11:55:43.628224008Z at > java.base/java.util.concurrent.AbstractExecutorService.submit(Unknown > Source) > 2025-07-11T11:55:43.628236311Z at > org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:769) > 2025-07-11T11:55:43.628238350Z at > org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:420) > 2025-07-11T11:55:43.628239666Z at > org.apache.catalina.startup.HostConfig.start(HostConfig.java:1621) > 2025-07-11T11:55:43.628241335Z at > org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:303) > 2025-07-11T11:55:43.628255587Z at > org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:109) > 2025-07-11T11:55:43.628256899Z at > org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:389) > 2025-07-11T11:55:43.628258590Z at > org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:336) > 2025-07-11T11:55:43.628259958Z at > org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:776) > 2025-07-11T11:55:43.628261506Z at > org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:772) > 2025-07-11T11:55:43.628263034Z at > org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) > 2025-07-11T11:55:43.628274187Z at > org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) > 2025-07-11T11:55:43.628275693Z at > org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) > 2025-07-11T11:55:43.628277030Z at > java.base/java.util.concurrent.FutureTask.run(Unknown Source) > 2025-07-11T11:55:43.628280369Z at > org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) > 2025-07-11T11:55:43.628281839Z at > java.base/java.util.concurrent.AbstractExecutorService.submit(Unknown > Source) > 2025-07-11T11:55:43.628283322Z at > org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) > 2025-07-11T11:55:43.628284925Z at > org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:203) > 2025-07-11T11:55:43.628286472Z at > org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) > 2025-07-11T11:55:43.628287734Z at > org.apache.catalina.core.StandardService.startInternal(StandardService.java:412) > 2025-07-11T11:55:43.628289236Z at > org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) > 2025-07-11T11:55:43.628290566Z at > org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:870) > 2025-07-11T11:55:43.628292404Z at > org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) > 2025-07-11T11:55:43.628293861Z at > org.apache.catalina.startup.Catalina.start(Catalina.java:761) > 2025-07-11T11:55:43.628295318Z at > java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown > Source) > 2025-07-11T11:55:43.628301199Z at > java.base/java.lang.reflect.Method.invoke(Unknown Source) > 2025-07-11T11:55:43.628302697Z at > org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) > 2025-07-11T11:55:43.628304266Z at > org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) > 2025-07-11T11:55:43.628305690Z Caused by: > org.apache.catalina.LifecycleException: Failed to start component > [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/demoapp]] > 2025-07-11T11:55:43.628307498Z at > org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:406) > 2025-07-11T11:55:43.628309026Z at > org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:179) > 2025-07-11T11:55:43.628310551Z at > org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:599) > 2025-07-11T11:55:43.628312065Z ... 35 more > 2025-07-11T11:55:43.628313380Z Caused by: java.lang.NullPointerException: > Cannot invoke "org.eclipse.microprofile.auth.LoginConfig.authMethod()" > because "loginConfig" is null > 2025-07-11T11:55:43.628315144Z at > org.apache.tomee.microprofile.jwt.MPJWTInitializer.onStartup(MPJWTInitializer.java:45) > 2025-07-11T11:55:43.628316658Z at > org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4464) > 2025-07-11T11:55:43.628320249Z at > org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) > 2025-07-11T11:55:43.628321622Z ... 36 more > 2025-07-11T11:55:43.632485224Z 11-Jul-2025 11:55:43.632 INFO [main] > java.lang.reflect.Method.invoke Deployment of web application archive > [/usr/local/tomee/webapps/demoapp.war] has finished in [3,177] ms > 2025-07-11T11:55:43.637611803Z 11-Jul-2025 11:55:43.637 INFO [main] > java.lang.reflect.Method.invoke Starting ProtocolHandler ["http-nio-8080"] > 2025-07-11T11:55:43.649430271Z 11-Jul-2025 11:55:43.649 INFO [main] > java.lang.reflect.Method.invoke Server startup in [3311] milliseconds > ``` > Here's how I configured it: > > ``` > @ApplicationScoped > @ApplicationPath("/api") > @LoginConfig(authMethod="MP-JWT") > @DeclareRoles({ > "admin-role", > "user-role" > }) > public class HelloApplication extends Application { > > } > > // is a separate class > @Path("/v1") > @Produces("text/plain") > public class HelloResource { > > @GET > @Path("/admin") > @RolesAllowed("admin-role") > public String helloAdmin() { > return "Hello, Admin!"; > } > > @GET > @Path("/user") > public String hello() { > return "Hello, user!"; > } > > } > ``` > > In `src/main/resources/META-INF/microprofile-config.properties` I have: > ``` > # JWT Configuration > mp.jwt.verify.issuer=http://auth.localhost:8090/realms/myrealm > mp.jwt.verify.publickey.location= > http://auth.localhost:8090/realms/myrealm/protocol/openid-connect/certs > ``` > and my `src/main/webapp/WEB-INF/web.xml` contains: > ``` > <?xml version="1.0" encoding="UTF-8"?> > <web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" > xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee > https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd" > version="6.0"> > > > </web-app> > ``` > > I run gradle war, mount it to my tomee container's deployment dir and start > it. Again, this exact setup worked perfectly with Payara - the idea was to > make sure the config is correct before trying to solve startup issue in > TomEE (sure, TomEE might require something differently). > > > Note that removing `@LoginConfig(authMethod="MP-JWT")` annotation on the > class and using: > ``` > <login-config> > <auth-method>MP-JWT</auth-method> > </login-config> > ``` > doesn't have the same effect! There is no such startup error but all > resources return `404 Not found`. > > Also note that I have tested with various other TomEE flavours of version > 10 - but no difference.