Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LinkageError in Weld/CDI in combination with jakarta.servlet.jsp.JspApplicationContext #6123

Closed
christophs78 opened this issue Apr 1, 2021 · 9 comments

Comments

@christophs78
Copy link

Jetty version
11.0.2

Java version
11.0.10

OS type/version
Windows 10

Description
Running mvn clean jetty:run on primefaces/primefaces-test#76 results in:

[WARNING] Failed startup of context o.e.j.m.p.MavenWebAppContext@6707a4bf{/primefaces-test,[file:///C:/Users/chris/IdeaProjects/christophs78_primefaces-test/src/main/webapp/, jar:file:///C:/Users/chris/.m2/repository/org/glassfish/jakarta.faces/3.0.0/jakarta.faces-3.0.0.jar!/META-INF/resources, jar:file:///C:/Users/chris/.m2/repository/org/primefaces/primefaces/10.0.0/primefaces-10.0.0-jakarta.jar!/META-INF/resources],UNAVAILABLE}{file:///C:/Users/chris/IdeaProjects/christophs78_primefaces-test/src/main/webapp/}
java.lang.LinkageError: loader constraint violation: when resolving interface method 'void jakarta.servlet.jsp.JspApplicationContext.addELResolver(jakarta.el.ELResolver)' the class loader org.eclipse.jetty.webapp.WebAppClassLoader @461c3709 of the current class, org/jboss/weld/environment/servlet/WeldServletLifecycle, and the class loader org.codehaus.plexus.classworlds.realm.ClassRealm @1e1e9ef3 for the method's defining class, jakarta/servlet/jsp/JspApplicationContext, have different Class objects for the type jakarta/el/ELResolver used in the signature (org.jboss.weld.environment.servlet.WeldServletLifecycle is in unnamed module of loader org.eclipse.jetty.webapp.WebAppClassLoader @461c3709, parent loader org.codehaus.plexus.classworlds.realm.ClassRealm @1e1e9ef3; jakarta.servlet.jsp.JspApplicationContext is in unnamed module of loader org.codehaus.plexus.classworlds.realm.ClassRealm @1e1e9ef3, parent loader 'bootstrap')
    at org.jboss.weld.environment.servlet.WeldServletLifecycle.initialize (WeldServletLifecycle.java:221)
    at org.jboss.weld.environment.servlet.EnhancedListener.onStartup (EnhancedListener.java:62)
    at org.eclipse.jetty.servlet.ServletContainerInitializerHolder.doStart (ServletContainerInitializerHolder.java:148)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:93)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start (ContainerLifeCycle.java:171)
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart (ContainerLifeCycle.java:114)
    at org.eclipse.jetty.servlet.ServletContextHandler$ServletContainerInitializerStarter.doStart (ServletContextHandler.java:1660)
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start (AbstractLifeCycle.java:93)
    at org.eclipse.jetty.servlet.ServletContextHandler.startContext (ServletContextHandler.java:369)
    at org.eclipse.jetty.webapp.WebAppContext.startContext (WebAppContext.java:1304)
    at org.eclipse.jetty.server.handler.ContextHandler.doStart (ContextHandler.java:880)
    at org.eclipse.jetty.servlet.ServletContextHandler.doStart (ServletContextHandler.java:306)
    at org.eclipse.jetty.webapp.WebAppContext.doStart (WebAppContext.java:532)
    at org.eclipse.jetty.maven.plugin.MavenWebAppContext.doStart (MavenWebAppContext.java:294)
@joakime
Copy link
Contributor

joakime commented Apr 1, 2021

I was able to reproduce both in jetty:run and in a standalone ${jetty.base}

The base I have ...

[primefaces-11]$ tree
.
├── resources
│   └── jetty-logging.properties
├── start.d
│   ├── annotations.ini
│   ├── deploy.ini
│   ├── http.ini
│   ├── jsp.ini
│   └── websocket.ini
└── webapps
    └── primefaces-test-1.0-SNAPSHOT.war

I had to make 2 changes to make it work (in standalone Jetty)

  1. Deleted the weld Listener in the primefaces-test WEB-INF/web.xml (it's not recommended, and not supported in a cross container way)
    <listener>
        <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
    </listener>

You can see this from the error messages it produces ...

Apr 01, 2021 5:13:53 PM org.jboss.weld.environment.servlet.EnhancedListener onStartup
INFO: WELD-ENV-001008: Initialize Weld using ServletContainerInitializer
Apr 01, 2021 5:13:53 PM org.jboss.weld.bootstrap.WeldStartup <clinit>
INFO: WELD-000900: 4.0.1 (Final)
Apr 01, 2021 5:13:53 PM org.jboss.weld.bootstrap.WeldStartup startContainer
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Apr 01, 2021 5:13:53 PM org.jboss.weld.bootstrap.events.BeforeBeanDiscoveryImpl addAnnotatedType
WARN: WELD-000146: BeforeBeanDiscovery.addAnnotatedType(AnnotatedType<?>) used for class com.sun.faces.flow.FlowDiscoveryCDIHelper is deprecated from CDI 1.1!
Apr 01, 2021 5:13:53 PM org.jboss.weld.environment.servlet.WeldServletLifecycle initialize
INFO: WELD-ENV-001001: No supported servlet container detected, CDI injection will NOT be available in Servlets, Filters or Listeners

Let weld use it's ServletContainerInitializer, that does the correct thing.

  1. Add jakarta. to the system classes.
[primefaces-11]$ cat start.d/jsp.ini 
# --------------------------------------- 
# Module: jsp
# Enables JSP for all web applications deployed on the server.
# --------------------------------------- 
jetty.webapp.addSystemClasses+=,jakarta.
--module=jsp

@janbartel @gregw should we add jakarta. to the default system classes on Jetty 11.x, or just the use of apache-el? WDYT?

https://github.com/eclipse/jetty.project/blob/jetty-11.0.x/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java#L166-L171
https://github.com/eclipse/jetty.project/blob/c627300a945828614ca5633f823db1de9e06f0ab/jetty-webapp/src/main/java/org/eclipse/jetty/webapp/WebAppContext.java#L166-L171

@janbartel
Copy link
Contributor

@christophs78 can you confirm that primefaces has been configured for the container's classpath and not on the webapp's classpath? As per instructions in the jetty doco here in section "Using JSF Taglibs": https://www.eclipse.org/jetty/documentation/jetty-9/index.html#jsp-support

@christophs78
Copy link
Author

Propably stupid question: How can i do
jetty.webapp.addSystemClasses+=,jakarta.
via jetty-maven-plugin?

@christophs78
Copy link
Author

@christophs78 can you confirm that primefaces has been configured for the container's classpath and not on the webapp's classpath? As per instructions in the jetty doco here in section "Using JSF Taglibs": https://www.eclipse.org/jetty/documentation/jetty-9/index.html#jsp-support

I tried this today, but it does not seem to make a difference. (And this may create new challenges to stay compatible with Tomcat.)

@janbartel
Copy link
Contributor

@joakime IMO "jakarta. " should definitely be in the default SystemClasses.

@janbartel
Copy link
Contributor

@christophs78 you don't need to set the system classes. The problem is that weld in transitively pulling in the jakarta.el-api jar, which is duplicating the one that is on the container classpath. You can simply put in:

       <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet-core</artifactId>
            <version>4.0.1.Final</version>
            <exclusions>
                <exclusion>
                    <groupId>jakarta.el</groupId>
                    <artifactId>jakarta.el-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

Weld should probably have made their dependency optional.

@joakime joakime changed the title LinkageError in combination with jakarta.servlet.jsp.JspApplicationContext LinkageError in Weld/CDI in combination with jakarta.servlet.jsp.JspApplicationContext Apr 2, 2021
@joakime
Copy link
Contributor

joakime commented Apr 2, 2021

@joakime IMO "jakarta. " should definitely be in the default SystemClasses.

Opened PR #6126 for this specifically.

@hantsy
Copy link
Contributor

hantsy commented Apr 18, 2021

@joakime Got it work on an external Jetty server, https://github.com/hantsy/jakartaee9-servlet-starter-boilerplate/. Is there a simple way to run all of these(CDI, JSF) in an embbeded jetty(via mvn jetty:run)?

@janbartel
Copy link
Contributor

Closing as the issue is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants