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

jetty-maven-plugin doesn't work as expected with Weld CDI #10895

Closed
astappiev opened this issue Nov 14, 2023 · 8 comments
Closed

jetty-maven-plugin doesn't work as expected with Weld CDI #10895

astappiev opened this issue Nov 14, 2023 · 8 comments
Labels
Bug For general bugs on Jetty side

Comments

@astappiev
Copy link

astappiev commented Nov 14, 2023

Jetty version(s)
11.0.18 and 12.0.3

Jetty Environment
ee10

Java version/vendor (use: java -version)
openjdk version "21" 2023-09-19 LTS
OpenJDK Runtime Environment Corretto-21.0.0.35.1 (build 21+35-LTS)

OS type/version
Win 11

Description
I'm trying to use jetty-maven-plugin:11.0.18/jetty-ee10-maven-plugin:12.0.3 with weld-servlet-core:5.1.2.Final and according to Weld documentation it should be working out of the box:

Jetty 11 and newer are supported. Context activation/deactivation and dependency injection into Servlets, Filters and Servlet listeners works out of the box.
No further configuration is needed when starting Jetty as an embedded webapp server from within another Java program.

But it doesn't work as expected, the log says:

org.jboss.weld.environment.servletWeldServlet:211 - WELD-ENV-001001: No supported servlet container detected, CDI injection will NOT be available in Servlets, Filters or Listeners

When I set it manually to Jetty:

<context-param>
    <param-name>org.jboss.weld.environment.container.class</param-name>
    <param-value>org.jboss.weld.environment.jetty.JettyContainer</param-value>
</context-param>

It tries to read org.eclipse.jetty.webapp.DecoratingListener, which is empty. Before, it also reads org.eclipse.jetty.cdi which is also empty.

java.lang.NullPointerException: null
	at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011) ~[?:?]
	at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006) ~[?:?]
	at org.eclipse.jetty.util.Attributes$Mapped.setAttribute(Attributes.java:265) ~[?:?]
	at org.eclipse.jetty.util.Attributes$Layer.setAttribute(Attributes.java:507) ~[?:?]
	at org.eclipse.jetty.ee10.servlet.ServletContextHandler$ServletContextApi.setAttribute(ServletContextHandler.java:2893) ~[?:?]

and ended up with

org.jboss.weld.environment.servletJetty:109 - WELD-ENV-001202: Unable to create JettyWeldInjector. CDI injection will not be available in Servlets, Filters or Listeners.

Of course, I tried other options mentioned in Weld's documentation

  1. Adding <modules>cdi-decorate</modules> doesn't change anything
  2. Binding BeanManager to Jetty JNDI results in an error that jakarta.enterprise.inject.spi.BeanManager is empty.

I would be glad to receive some feedback and ideas on where to look, it seems like Jetty does not initialise SPI.

How to reproduce?
https://github.com/astappiev/primefaces-test/tree/jetty12 can be used as a reproducer; when the server starts, it prints that no servlet container is detected.

@astappiev astappiev added the Bug For general bugs on Jetty side label Nov 14, 2023
@joakime
Copy link
Contributor

joakime commented Nov 14, 2023

First things I noticed in your question ...

<context-param>
    <param-name>org.jboss.weld.environment.container.class</param-name>
    <param-value>org.jboss.weld.environment. Jetty.JettyContainer</param-value>
</context-param>

Double check that XML, it looks bad / invalid.
The space in the <param-value> shouldn't be there, and the capitalization is important as you are referencing a class file. (what you pasted is not the accurate classname)

@joakime
Copy link
Contributor

joakime commented Nov 14, 2023

Also, as far as Weld versions go ...

For Jetty 10.x you would use Weld 3.1.x
For Jetty 11.x you would use Weld 4.0.x
For Jetty 12.x / ee8 you would use Weld 3.1.x (eg: 3.1.9.Final)
For Jetty 12.x / ee9 you would use Weld 4.0.x (eg: 4.0.3.Final)
For Jetty 12.x / ee10 you would use Weld 5.1.x (eg: 5.1.2.Final)

@joakime
Copy link
Contributor

joakime commented Nov 14, 2023

How to reproduce?
https://github.com/primefaces/primefaces-test can be used as a reproducer; when the server starts, it prints that no servlet container is detected.

That doesn't work for us.
Why are you using Servlet API 4.0.1 with Jetty 9.4.x ?
That's incompatible. Jetty 9.x is Servlet 3.1, and Jetty 10.x is Servlet 4.0

Your code is using javax.servlet.* namespace, that means you are stuck on Servlet 3.1 or Servlet 4.0
That means you cannot use Jetty 11 (for Servlet 5) or Jetty 12/ee10 (Servlet 6) or Jetty 12/ee9 (Servlet 5) as those are on the jakarta.servlet.* namespace.
You have to use Jetty 10 or Jetty 12/ee8 for Servlet 4.0

Also, AFAIK, Weld 4 and Weld 5 do not support the older javax.servlet.* namespace.

@joakime
Copy link
Contributor

joakime commented Nov 14, 2023

@astappiev
Copy link
Author

Thank you, @joakime, for taking a look into it.

Double check that XML, it looks bad / invalid.

Yes, indeed, the formatting was damaged by the Grammarly plugin in the message (it capitalized Jetty in all places).

That doesn't work for us.

Sorry for misleading, the link should be to specific brunch which uses Jetty 11.

I have updated it with Jetty 12 in my fork, you can start with it https://github.com/astappiev/primefaces-test/tree/jetty12

@joakime joakime changed the title Jetty-Maven-plugin doesn't work as expected with Weld CDI jetty-maven-plugin doesn't work as expected with Weld CDI Nov 15, 2023
@joakime
Copy link
Contributor

joakime commented Nov 15, 2023

Looks like weld is attempting to use the old school ServletContainerInitializer org.jboss.weld.environment.servlet.EnhancedListener that was created back during Jetty 7/8 days, which worked OK on Jetty 9, and stopped working reliably on Jetty 10+ (some configurations would work, most wouldn't, complex projects are surprised when some features work, and others features do not).

ERROR: WELD-ENV-001202: Unable to create JettyWeldInjector. CDI injection will not be available in Servlets, Filters or Listeners.
java.lang.NullPointerException
	at java.base/java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
	at java.base/java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
	at org.eclipse.jetty.util.Attributes$Mapped.setAttribute(Attributes.java:265)
	at org.eclipse.jetty.util.Attributes$Layer.setAttribute(Attributes.java:507)
	at org.eclipse.jetty.ee10.servlet.ServletContextHandler$ServletContextApi.setAttribute(ServletContextHandler.java:2893)
	at org.jboss.weld.environment.jetty.JettyContainer.initialize(JettyContainer.java:101)
	at org.jboss.weld.environment.servlet.WeldServletLifecycle.initialize(WeldServletLifecycle.java:214)
	at org.jboss.weld.environment.servlet.EnhancedListener.onStartup(EnhancedListener.java:66)

This EnhancedListener does not work on it's own anymore, you need to do more, before it.

This "more" is solved by the Jetty generic CDI initialization (works with weld and openweb).

You can find that in the jetty-ee10-cdi artifact (on Jetty 12) and jetty-cdi (on Jetty 10 / Jetty 11)

This will cause 2 things to happen.

  1. The CdiConfiguration is executed for the WebAppContext
  2. The CdiServletContainerInitializer is used to initialize the CDI layer.
[joakim@hyperion astappiev-primefaces-test][jetty12*]$ git branch -v
* jetty12 b84d27f chore: remove unnecessary web.xml filtering
  master  5423124 Bump jetty-maven-plugin from 9.4.50.v20221201 to 9.4.51.v20230217 (#242)

[joakim@hyperion astappiev-primefaces-test][jetty12*]$ git diff
diff --git a/pom.xml b/pom.xml
index 2d54e13..5da52f1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,13 @@
                         <idleTimeout>60000</idleTimeout>
                     </httpConnector>
                 </configuration>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.eclipse.jetty.ee10</groupId>
+                        <artifactId>jetty-ee10-cdi</artifactId>
+                        <version>${jetty.version}</version>
+                    </dependency>
+                </dependencies>
             </plugin>
         </plugins>
     </build>

This should work for you.

Keep in mind that on weld, there's multiple ways it can be initialized.

See our testcase for possible webapp setups on weld (and the comments indicating the pros / cons of each setup)

https://github.com/jetty/jetty.project/blob/jetty-12.0.x/jetty-ee10/jetty-ee10-tests/jetty-ee10-test-cdi/src/test/java/org/eclipse/jetty/ee10/cdi/tests/EmbeddedWeldTest.java#L81-L133

@astappiev
Copy link
Author

Thank you very much, that solved my issue.

@astappiev
Copy link
Author

I have created a similar issue on Weld tracker before, and they pointed me out to these two discussions, which adds a little more light to this topic:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug For general bugs on Jetty side
Projects
None yet
Development

No branches or pull requests

2 participants