在Tomcat 8/Jetty 9部署Jersey+Weld Web应用时遇错误求助
Hey there, let's break down what's causing these errors and walk through fixes step by step.
First Error: NoSuchMethodError in Weld's Preconditions.checkNotNull
This is almost always a classpath dependency conflict, even though you can see the method exists in your target Weld version. Here's why:
- Jersey's CDI integration dependencies (like
jersey-weld2-seorjersey-cdi1x) likely pull in an older version of Weld under the hood. - At runtime, the JVM loads that older Weld class (which doesn't have the
checkNotNullmethod with the signature(Ljava/lang/Object;)V) instead of your explicitly declaredweld-servlet 2.4.6-Final.
Fix Steps:
Identify conflicting dependencies
Run this Maven command to see all Weld-related dependencies in your project:mvn dependency:tree -Dincludes=org.jboss.weldLook for any Weld artifacts with versions older than 2.4.6-Final.
Exclude old Weld versions from Jersey dependencies
Update yourpom.xmlto exclude all Weld modules from Jersey's CDI dependencies, ensuring only your declaredweld-servletis used:<dependency> <groupId>org.glassfish.jersey.ext.cdi</groupId> <artifactId>jersey-weld2-se</artifactId> <exclusions> <exclusion> <groupId>org.jboss.weld</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.jersey.ext.cdi</groupId> <artifactId>jersey-cdi1x</artifactId> <exclusions> <exclusion> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> </exclusion> <exclusion> <groupId>org.jboss.weld</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.jersey.ext.cdi</groupId> <artifactId>jersey-cdi1x-servlet</artifactId> <exclusions> <exclusion> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> </exclusion> <exclusion> <groupId>org.jboss.weld</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>Keep using the Weld servlet uber jar
Avoid splittingweld-servletinto individualweld-core/weld-servlet-coredependencies—it's designed as an uber jar to include all necessary components, and splitting often leads to missing or mismatched classes.
Second Error: ArrayIndexOutOfBoundsException in ExternalRequestScopeConfigurator
This happens when Jersey can't properly access the CDI BeanManager during initialization, usually due to:
- Missing Weld context configuration for Tomcat
- Mismatched versions between Jersey and Weld
- Incomplete dependency setup after splitting the Weld uber jar
Fix Steps:
Add Tomcat-specific Weld configuration
Update yourweb.xmlwith context parameters to help Weld integrate with Tomcat correctly:<context-param> <param-name>org.jboss.weld.environment.servlet.container.class</param-name> <param-value>org.jboss.weld.environment.tomcat.TomcatContainer</param-value> </context-param> <context-param> <param-name>javax.enterprise.inject.scan.implicit</param-name> <param-value>true</param-value> </context-param> <!-- Keep your existing listener and servlet config --> <listener> <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class> </listener> <servlet> <servlet-name>PIIApplication</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>com.example.project.RESTService</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>PIIApplication</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>Lock down Jersey versions
Your current Jersey dependencies don't have explicit versions, which lets Maven pull arbitrary (potentially incompatible) versions. Weld 2.4.6-Final works best with Jersey 2.25.x to 2.30.x. Add a version property and apply it to all Jersey dependencies:<properties> <jersey.version>2.29.1</jersey.version> </properties> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-server</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>${jersey.version}</version> </dependency> <!-- Apply ${jersey.version} to all other Jersey artifacts -->
Additional Notes on the CDI Webapp Example
The Jersey CDI webapp example failing in Tomcat is also a version conflict issue. Adjust the example's pom.xml to use the same Jersey/Weld versions you've fixed in your project, and apply the same dependency exclusion rules.
内容的提问来源于stack exchange,提问作者Saasira

