为什么CDI(使用JAXRS)在Open Libety Server中不起作用,但在Payara Server上可以正常工作?

问题描述 投票:0回答:1

我一直在尝试从Payara服务器切换到Open Liberty,但是我遇到了一个问题:我的代码在Payara上运行良好,但在Open Liberty上运行不好。这是说明问题的最简单的代码测试:

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();
    }
}

您可能会猜到,此代码在Payara服务器上有效,当我尝试在Open Liberty服务器上运行它时,出现以下错误:

[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

最后一个异常告诉我configuration.getProperties()在Test.java的post构造函数中返回null。 为什么在Open Liberty中表现不这样,而在Payara中却没有?另外,如果我没有在TestResources.java文本方法中调用test.getName()并仅返回一个随机字符串,则不会出现任何错误。 这引起了@PostConstructor方法何时被调用的问题?我认为在Bean完全初始化时它会被调用,并且应该在TestResources.java中执行测试方法之前发生。我在这里缺少什么吗?

请注意,我在maven中使用的唯一依赖项是具有提供范围的完整jakartaee-8。

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>
jakarta-ee jax-rs cdi open-liberty java-ee-8
1个回答
0
投票

根据我的最初回答,我认为这是OpenLiberty的错误,但是根据JAX-RS 2.1规范的10.2.8节,

客户端和服务器运行时配置均可通过@Context注入。这些配置可用于注入提供程序(客户机或服务器)和资源类(仅服务器)。

该规范没有要求CDI bean支持特定的JAX-RS @Context批注,仅支持资源和提供程序。

[Payara似乎超出了规范,并支持CDI bean上的@Context注释。

© www.soinside.com 2019 - 2024. All rights reserved.