jersey icon indicating copy to clipboard operation
jersey copied to clipboard

Post Jersey upgrade from 2.37 to 3.1.9 getting java.lang.NoSuchMethodException: Could not find a suitable constructor

Open ilapavuluri opened this issue 8 months ago • 8 comments

Hi Team,

Mine is a Tomcat based application which is working fine with Tomcat 9.x, Servlet 4.x and Jersey 2.37

with below web.xml:

AppServlet org.glassfish.jersey.servlet.ServletContainer jakarta.ws.rs.Application com.broadcom.visualizer.rest.app.AppServlet 1 true

My AppServlet looks like below:

public class AppServlet extends ResourceConfig {

......

// Application startup

@Inject
public AppServlet(ServiceLocator serviceLocator) throws Exception {
    logger.info("Application initialization started!!!");

   .....
  

    // Enable this to instantiate bound classes, with Immediate as the scope, during binding phase
    // rather than when accessed for the first time
   // ServiceLocator serviceLocator =  ServiceLocatorUtilities.createAndPopulateServiceLocator();
    ServiceLocatorUtilities.enableImmediateScope(serviceLocator);

    register(new AbstractBinder() {
        protected void configure() {
            .......
            bind(actorSystem).to(ActorSystem.class);
            bind(I18NMessages.class).to(I18NMessages.class).in(Immediate.class);
            bind(GraphDataManager.class).to(GraphDataManager.class).in(Immediate.class);
            bind(CacheManager.class).to(CacheManager.class).in(Singleton.class);
          .....
        }
    });

   .....
}

@PreDestroy
private void shutdown() {
   ......
}

}

After I upgrade to Tomcat 10.1, Servlet 6.0.0 and Jersey to 3.1.9, I am getting below exception and application is not starting:

Java.lang.NoSuchMethodException: Could not find a suitable constructor...... at org.glassfish.jersey.inject.hk2.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:168) at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:157) at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:1043) at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:984) at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1088) at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1080) at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.createAndInitialize(AbstractHk2InjectionManager.java:199) at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.createAndInitialize(ImmediateHk2InjectionManager.java:30) at org.glassfish.jersey.server.ApplicationConfigurator.createApplication(ApplicationConfigurator.java:114) at org.glassfish.jersey.server.ApplicationConfigurator.init(ApplicationConfigurator.java:72) at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:306) at java.base/java.util.Arrays$ArrayList.forEach(Arrays.java:4204) at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:306) at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:273) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:314) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:339) at jakarta.servlet.GenericServlet.init(GenericServlet.java:143) at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:121) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:837) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:794) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:698) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4224) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4511) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.ca

Due to this I am not able to upgrade to latest versions.

Appreciate any help on this.

Thanks Ashok.

ilapavuluri avatar Apr 10 '25 16:04 ilapavuluri

Double-check the imports, for example, if you use jakarta.inject.Singleton.class vs javax.inject.Singleton.class. Otherwise, provide more info about the issue. The current report is not complete - no imports are visible, stack-trace is not complete. Dependencies are not included. It's not solvable in this state.

senivam avatar Apr 10 '25 16:04 senivam

Thank you @senivam for the quick response, here are my imports

import java.sql.SQLException;

import jakarta.annotation.PreDestroy; import jakarta.ws.rs.ApplicationPath;

import javax.inject.Inject; import javax.inject.Singleton;

import org.glassfish.hk2.api.Immediate; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.ServiceLocatorUtilities; import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory;

import org.apache.pekko.actor.ActorSystem; import net.sf.ehcache.CacheManager;

public class AppServlet extends ResourceConfig {

private Config config;
private DBConnectionPoolManager dbConnectionPoolManager;


// Application startup

@Inject
public AppServlet(ServiceLocator serviceLocator) throws Exception {
    logger.info("Application initialization started!!!");

.....

// Enable this to instantiate bound classes, with Immediate as the scope, during binding phase
// rather than when accessed for the first time

// ServiceLocator serviceLocator = ServiceLocatorUtilities.createAndPopulateServiceLocator(); ServiceLocatorUtilities.enableImmediateScope(serviceLocator);

register(new AbstractBinder() {
    protected void configure() {
        .......
        bind(actorSystem).to(ActorSystem.class);
        bind(I18NMessages.class).to(I18NMessages.class).in(Immediate.class);
        bind(GraphDataManager.class).to(GraphDataManager.class).in(Immediate.class);
        bind(CacheManager.class).to(CacheManager.class).in(Singleton.class);
      .....
    }
});

..... }

@PreDestroy private void shutdown() { ...... }

ilapavuluri avatar Apr 10 '25 17:04 ilapavuluri

Here is the complete error stack:

SEVERE: Servlet.init() for servlet [.....] threw exception MultiException stack 1 of 1 java.lang.NoSuchMethodException: Could not find a suitable constructor in ...... class. at org.glassfish.jersey.inject.hk2.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:168) at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:157) at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:1043) at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:984) at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1088) at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1080) at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.createAndInitialize(AbstractHk2InjectionManager.java:199) at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.createAndInitialize(ImmediateHk2InjectionManager.java:30) at org.glassfish.jersey.server.ApplicationConfigurator.createApplication(ApplicationConfigurator.java:114) at org.glassfish.jersey.server.ApplicationConfigurator.init(ApplicationConfigurator.java:72) at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:306) at java.base/java.util.Arrays$ArrayList.forEach(Arrays.java:4204) at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:306) at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:273) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:314) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:339) at jakarta.servlet.GenericServlet.init(GenericServlet.java:143) at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:121) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:837) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:794) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:698) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4224) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4511) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:772) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:203) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:415) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:870) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.startup.Catalina.start(Catalina.java:761) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)

Apr 10, 2025 10:40:35 PM org.apache.catalina.core.StandardContext loadOnStartup SEVERE: Servlet [....] in web application [/....] threw load() exception java.lang.NoSuchMethodException: Could not find a suitable constructor in ..... class. at org.glassfish.jersey.inject.hk2.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:168) at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:157) at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:1043) at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:984) at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1088) at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:1080) at org.glassfish.jersey.inject.hk2.AbstractHk2InjectionManager.createAndInitialize(AbstractHk2InjectionManager.java:199) at org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager.createAndInitialize(ImmediateHk2InjectionManager.java:30) at org.glassfish.jersey.server.ApplicationConfigurator.createApplication(ApplicationConfigurator.java:114) at org.glassfish.jersey.server.ApplicationConfigurator.init(ApplicationConfigurator.java:72) at org.glassfish.jersey.server.ApplicationHandler.lambda$initialize$0(ApplicationHandler.java:306) at java.base/java.util.Arrays$ArrayList.forEach(Arrays.java:4204) at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:306) at org.glassfish.jersey.server.ApplicationHandler.(ApplicationHandler.java:273) at org.glassfish.jersey.servlet.WebComponent.(WebComponent.java:314) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:154) at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:339) at jakarta.servlet.GenericServlet.init(GenericServlet.java:143) at jakarta.servlet.http.HttpServlet.init(HttpServlet.java:121) at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:837) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:794) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:698) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4224) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4511) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:772) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1203) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1193) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:749) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:203) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:415) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:870) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:164) at org.apache.catalina.startup.Catalina.start(Catalina.java:761) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)

Apr 10, 2025 10:40:35 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-8080"] Apr 10, 2025 10:40:35 PM org.apache.catalina.startup.Catalina start INFO: Server startup in [10869] milliseconds

ilapavuluri avatar Apr 10 '25 17:04 ilapavuluri

Thanks for the additional information. Seen the imports:

import javax.inject.Inject;
import javax.inject.Singleton;

should be replaced to

import jakarta.inject.Inject;
import jakarta.inject.Singleton;

and check if the related dependency for the Inject is migrated as well:

<-- This is new one for Jakarta 10 -->
<dependency>
    <groupId>jakarta.inject</groupId>
    <artifactId>jakarta.inject-api</artifactId>
    <version>2.0.1</version>
</dependency>

senivam avatar Apr 10 '25 17:04 senivam

Thank you @senivam , After making the above changes Application is started, but looks like initialization didn't happen properly, I am getting below exception when I am triggering any of my REST API.

An exception mapping did not successfully produce and processed a response. Logging the exception propagated to the default exception mapper. java.lang.NullPointerException: Cannot invoke "....getI18NMessage(java.util.Locale)" because "this.i18nMessages" is null at ........AuthInterceptor.filter(AuthInterceptor.java:60) at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:108) at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:44) at org.glassfish.jersey.process.internal.Stages.process(Stages.java:173) at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:266) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248) at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244) at org.glassfish.jersey.internal.Errors.process(Errors.java:292) at org.glassfish.jersey.internal.Errors.process(Errors.java:274) at org.glassfish.jersey.internal.Errors.process(Errors.java:244) at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:266) at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:253) at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:696) at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:397) at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:349) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:358) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:312) at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) at java.base/java.lang.Thread.run(Thread.java:840)

I am guessing the below classes are not initialized properly in the AppServlet

register(new AbstractBinder() { protected void configure() { ....... bind(actorSystem).to(ActorSystem.class); bind(I18NMessages.class).to(I18NMessages.class).in(Immediate.class); bind(GraphDataManager.class).to(GraphDataManager.class).in(Immediate.class); bind(CacheManager.class).to(CacheManager.class).in(Singleton.class); ..... } });

and I18NMessages class looks like below:

@Singleton public class I18NMessages {

@Inject private I18NMessages(Config config) { .... }

}

ilapavuluri avatar Apr 10 '25 17:04 ilapavuluri

@senivam any help on the above?

Thanks Ashok.

ilapavuluri avatar Apr 10 '25 17:04 ilapavuluri

you can try marking the class directy by annotation:

@Immediate
@jakarta.inject.Singleton
public class I18NMessages {
    // class implementation
}

and then register it as a singleton within the binder:

bind(I18NMessages.class).to(I18NMessages.class).in(jakarta.inject.Singleton.class);

But, as I see, your code is quite complex, so consider focusing on the migration with help of the migration guide for the Jersey-related part.

senivam avatar Apr 10 '25 19:04 senivam

in(Immediate.class) probably does nothing, as Immediate is no Scope recognised by Jersey.

jansupol avatar Apr 11 '25 13:04 jansupol

@senivam I have javax.inject references in other places as well, after replacing them with jakarta.inject issue resolved.

ilapavuluri avatar Jun 03 '25 10:06 ilapavuluri