Почему CDI (с JAXRS) не работает на Open Libety Server, но отлично работает на Payara Server? - PullRequest
0 голосов
/ 20 апреля 2020

Я пытался перейти с сервера 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() возвращает null в Test. java post constructor. Почему это ведет себя так в Open Liberty, а не в Payara? Также, если я не вызываю test.getName() в TestResources. java текстовый метод и просто возвращаю случайную строку, я не получаю никакой ошибка. Возникает вопрос, когда вызывается метод @PostConstructor? Я думал, что он вызывается, когда компонент полностью инициализируется, и это должно произойти до того, как метод теста будет выполнен в 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>

1 Ответ

2 голосов
/ 21 апреля 2020

В своем первоначальном ответе я предположил, что это была ошибка OpenLiberty, но в соответствии с JAX-RS 2.1 spe c, раздел 10.2.8 Конфигурация,

Конфигурации времени выполнения клиента и сервера доступны для инъекции через @Context. Эти конфигурации доступны для внедрения в провайдеры (клиент или сервер) и классы ресурсов (только сервер).

Спецификация c не предписывает компонентам CDI поддерживать спецификацию c JAX-RS @Context аннотации, только ресурсы и поставщики.

Похоже, что Payara выходит за рамки спецификации c и поддерживает аннотацию @Context для компонентов CDI.

...