I have been trying to switch from Payara server to Open Liberty, however I am faced with a problem: my code works well on Payara but does not work well on Open Liberty. Here is the simplest code test to illustrate the problem:
ApiEntryPoint.java
@ApplicationPath("/v1")
public class ApiEntryPoint extends Application {
@Override
public Map<String, Object> getProperties() {
Map<String, Object> props = new HashMap<String, Object>();
props.put("name", "This is my name");
return props;
}
}
Test.java
@ApplicationScoped
public class Test {
@Context
private Configuration configuration;
private String name;
@PostConstruct
private void init() {
name = (String) configuration.getProperties().get("name");
}
public String getName() {
return name;
}
}
TestResources.java
@Path("/test")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RequestScoped
public class TestResources {
@Inject
private Test test;
@GET
public String test(@Context HttpHeaders headers, @PathParam("id") int id) {
return test.getName();
}
}
As you may guess, this code works on Payara server and when I try to run it on Open Liberty server, I get the following error:
[err] org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke private void com.domain.test.Test.init() on com.domain.test.Test@74caba3d
[err] at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:85)
[err] at [internal classes]
[err] at com.domain.test.Test$Proxy$_$$_WeldClientProxy.getName(Unknown Source)
[err] at com.domain.test.TestResources.test(TestResources.java:25)
[err] at com.domain.test.TestResources$Proxy$_$$_WeldClientProxy.test(Unknown Source)
[err] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[err] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[err] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[err] at java.lang.reflect.Method.invoke(Method.java:498)
[err] at com.ibm.ws.jaxrs20.server.LibertyJaxRsServerFactoryBean.performInvocation(LibertyJaxRsServerFactoryBean.java:656)
[err] at [internal classes]
[err] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[err] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[err] at java.lang.Thread.run(Thread.java:748)
[err] Caused by: java.lang.reflect.InvocationTargetException
[err] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[err] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[err] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[err] at java.lang.reflect.Method.invoke(Method.java:498)
[err] at org.jboss.weld.injection.producer.DefaultLifecycleCallbackInvoker.invokeMethods(DefaultLifecycleCallbackInvoker.java:83)
[err] ... 64 more
[err] Caused by: java.lang.NullPointerException
[err] at com.domain.test.Test.init(Test.java:18)
[err] ... 69 more
The last exception tells me the that configuration.getProperties()
returns null in Test.java post constructor. Why is this behaving as such in Open Liberty and not in Payara? Also if I don't call test.getName()
in TestResources.java text method and just return a random string, I am not getting any error. This begs the question when is @PostConstructor method called? I thought it gets called when the bean is fully initialized and this should happen before the test method executes in TestResources.java. Is there something that I am missing here?
Note that the only dependency I am using in maven is the full jakartaee-8 with a scope of provided.
server.xml
<server description="new server">
<featureManager>
<feature>jakartaee-8.0</feature>
<feature>localConnector-1.0</feature>
</featureManager>
<keyStore password="mypassword"/>
<basicRegistry id="basic" realm="BasicRealm">
<user name="username" password="mypassword"/>
</basicRegistry>
<httpEndpoint httpPort="9080" httpsPort="9443" id="defaultHttpEndpoint"/>
<applicationManager autoExpand="true"/>
<ssl id="defaultSSLConfig" trustDefaultCerts="true"/>
<applicationMonitor updateTrigger="mbean"/>
<webApplication id="test" location="test-0.0.1-SNAPSHOT.war" name="test"/>
</server>
On my initial answer I assumed it was OpenLiberty's fault, but according to the JAX-RS 2.1 spec, section 10.2.8 Configuration,
Both the client and the server runtime configurations are available for injection via @Context. These configurations are available for injection in providers (client or server) and resource classes (server only).
The spec doesn't mandate CDI beans to support specific JAX-RS @Context
annotations, only resources and providers.
It seems that Payara goes beyond the spec, and supports the @Context
annotation on CDI beans.