Развертывание Resteasy случайно завершается ошибкой на Glassfish 4.1

У меня проблема с моим REST-приложением, использующим Resteasy. Когда я развертываю приложение с этими зависимостями

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-servlet-initializer</artifactId>
    <version>3.0.11.Final</version>
</dependency>

как описано здесь в Глава 3.5 иногда сервер корректно развертывает приложение и все работает нормально.

Но иногда я получаю

Error invoking ServletContainerInitializer 
org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer
java.lang.NullPointerException
    at org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer.register(ResteasyServletInitializer.java:109)
    at org.jboss.resteasy.plugins.servlet.ResteasyServletInitializer.onStartup(ResteasyServletInitializer.java:80)
    at org.apache.catalina.core.StandardContext.callServletContainerInitializers(StandardContext.java:6031)
    at com.sun.enterprise.web.WebModule.callServletContainerInitializers(WebModule.java:774)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:5929)
    at com.sun.enterprise.web.WebModule.start(WebModule.java:691)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1041)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:1024)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:747)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2286)
    at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1932)
    at com.sun.enterprise.web.WebApplication.start(WebApplication.java:139)
    at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
    at org.glassfish.internal.data.ModuleInfo.start(ModuleInfo.java:291)
    at org.glassfish.internal.data.ApplicationInfo.start(ApplicationInfo.java:352)
    at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:500)
    at com.sun.enterprise.v3.server.ApplicationLoaderService.processApplication(ApplicationLoaderService.java:406)
    at com.sun.enterprise.v3.server.ApplicationLoaderService.postConstruct(ApplicationLoaderService.java:243)
    at org.jvnet.hk2.internal.ClazzCreator.postConstructMe(ClazzCreator.java:329)
    at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:377)
    at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:461)
    at org.glassfish.hk2.runlevel.internal.AsyncRunLevelContext.findOrCreate(AsyncRunLevelContext.java:227)
    at org.glassfish.hk2.runlevel.RunLevelContext.findOrCreate(RunLevelContext.java:84)
    at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2258)
    at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:105)
    at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:87)
    at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.oneJob(CurrentTaskFuture.java:1162)
    at org.glassfish.hk2.runlevel.internal.CurrentTaskFuture$QueueRunner.run(CurrentTaskFuture.java:1147)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
]]

В исходниках ResteasyServletInitializer строка 109 это (с контекстом)

ServletRegistration.Dynamic reg = servletContext.addServlet(applicationClass.getName(), HttpServlet30Dispatcher.class);
reg.setLoadOnStartup(1); //Line 109
reg.setAsyncSupported(true);
reg.setInitParameter("javax.ws.rs.Application", applicationClass.getName());

Итак, я предполагаю, что это ошибка Glassfish, и Glassfish не может правильно вернуть правильный объект. Я не обнаружил, чтобы это происходило при передислокациях, после очистки osgi-кэша и т. д. Кажется, это довольно случайно.

Это кажется связанным и я пытался добавить

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

Но он все еще иногда дает сбой, хотя я бы сказал, что он выходит из строя немного реже. Принятый ответ из сообщения устарел, поскольку ссылка на него 3.9. RESTEasy как ServletContextListener, поэтому я не хочу пробовать это. Это похоже на уход от проблемы, а не на ее решение.

Моя версия Glassfish — это GlassFish Server Open Source Edition 4.1 (сборка 13).

Пожалуйста, помогите мне с этим.

Ваше здоровье


person drame    schedule 15.07.2015    source источник
comment
Я только что узнал, что при выполнении ResteasyServletInitializer мое приложение уже зарегистрировано. Но я не понимаю, в какой момент регистрируется приложение.   -  person drame    schedule 16.07.2015
comment
Просто была такая же проблема, вот как я сюда попал. В моем случае я заметил, что собственный org.glassfish.jersey.servlet.init.JerseyServletContainerInitializer Glassfish успешно инициализирует приложение непосредственно перед тем, как возникает эта ошибка.   -  person Rafael Chaves    schedule 23.07.2015
comment
Я заметил то же самое после отладки ResteasyServletInitializer. Я опубликовал еще один вопрос по этой теме: stackoverflow.com/questions/31458850/ . К сожалению ответов пока нет. Вам удалось решить проблему? Я решил это, как упоминалось в новом вопросе: (p.s. удаление jersey-container-servlet.jar из папки glassfish/modules/ работает);)   -  person drame    schedule 27.07.2015
comment
Добавил то, что я сделал в качестве ответа ниже. Другая возможность, о которой я упоминал для других конфликтов, заключалась в изменении загрузчика классов. модель делегирования, так как Glassfish по умолчанию не следует рекомендации спецификации сервлета о том, что с локальным загрузчиком классов следует обращаться перед загрузчиком родительского класса.   -  person Rafael Chaves    schedule 28.07.2015
comment
Я также читал об этом и пробовал делегат = ложь, но безрезультатно.   -  person drame    schedule 28.07.2015


Ответы (1)


В итоге я избежал этой проблемы, убедившись, что приложение WAR не включает RESTEasy.

Поэтому сейчас я строю две войны: одну с RESTEasy (что требуется для развертывания на Tomcat и Wildfly), другую без него (для развертывания на Glassfish). Это кажется лучше, чем требовать изменения установки Glassfish, но выполняет то же самое: позволяет избежать установки двух реализаций JAX-RS.

person Rafael Chaves    schedule 28.07.2015
comment
Это хорошее решение в вашем случае. К сожалению, у меня были проблемы с трикотажем, и поэтому я начал использовать resteasy в качестве альтернативы. Вот исходный пост, объясняющий мою проблему с трикотажем валидатор ограничений">stackoverflow.com/questions/31386683/. - person drame; 28.07.2015