Мой слух не может найти классы ejb модуля
Я новичок в EAR. Я разработал веб-модуль и модуль ejb, которые зависят друг от друга по функциональности. Для этого я пытаюсь заверить их в EAR. Я сопоставил оба модуля web и ejb в EAR и могу увидеть application.xml как
<display-name>EBS-ear</display-name>
<module>
<ejb>EBS-ejb.jar</ejb>
</module>
<module>
<web>
<web-uri>EBS-web.war</web-uri>
<context-root>EBS-web</context-root>
</web>
</module>
</application>
Но когда я пытаюсь выполнить EAR, мой сервер выдает ниже исключения
23:58:29,606 ERROR [io.undertow.request] (default task-5) UT005023: Exception handling request to /EBS-web/: java.lang.NoClassDefFoundError: com/ebs/service/UserAuthorisationService
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getConstructor(Unknown Source)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.verifyAction(XmlConfigurationProvider.java:480)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addAction(XmlConfigurationProvider.java:429)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:556)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:295)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:112)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:264)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:967)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:435)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:479)
at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:57)
at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:111)
at org.wildfly.extension.undertow.security.RunAsLifecycleInterceptor.init(RunAsLifecycleInterceptor.java:84)
at io.undertow.servlet.core.LifecyleInterceptorInvocation.proceed(LifecyleInterceptorInvocation.java:97)
at io.undertow.servlet.core.ManagedFilter.createFilter(ManagedFilter.java:80)
at io.undertow.servlet.core.ManagedFilter.getFilter(ManagedFilter.java:66)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.jsp.JspFileHandler.handleRequest(JspFileHandler.java:32)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.ebs.service.UserAuthorisationService from [Module "deployment.EBS-web.war:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93)
... 61 more
Что я могу понять из вышесказанного, так это то, что EAR не может найти классы, присутствующие в модуле EJB, и поэтому выдает исключение. Я использую сервер WildFLy 10 и затмение IDE.
1 ответ
EAR-файл - это просто контейнер для различных корпоративных модулей (JJ-файлы EJB, WAR-файлы и обычные JAR-файлы) с некоторыми четко определенными (но часто неправильно понимаемыми) правилами, для которых классы могут видеть какие.
В большинстве случаев вы увидите файл EAR со следующей внутренней структурой:
EAR
\-lib
| \- utilityA.jar
| \- utilityB.jar
| \- ...
|- ejb-jarC.jar
|- ejb-jarD.jar
|- ...
|- warE.jar
|- warF.jar
|- ...
Для целей видимости класса в этом EAR выше показано пять модулей:
- модуль lib
- EJB-jar1.jar
- EJB-jar2.jar
- war1.jar
- war2.jar
где:
- Все банки в модуле lib считаются находящимися в одном модуле;
- Все jar и классы в каждом файле WAR считаются находящимися в одном модуле;
- Каждый ejb-jar является независимым модулем.
Как правило, у каждого модуля есть свой загрузчик классов.
Теперь JBossAS/WildFly немного ослабляет правила видимости классов, чтобы упростить жизнь разработчикам (и по историческим причинам). На этих реализациях сервера действуют следующие правила:
- Каждый WAR-модуль может видеть свои собственные классы, классы в каждом jar-файле EJB и классы в каждом jar-каталоге в каталоге EAR/lib
- он не может видеть классы в других модулях WAR;
- Каждый модуль EJB может видеть свои собственные классы, классы в других модулях EJB и классы в каждом jar-каталоге в каталоге EAR/lib;
- он не может видеть классы в любых модулях WAR;
- Классы в модуле EAR/lib могут видеть только друг друга:
- они не могут видеть классы в каких-либо EJB-модулях или WAR-модулях
Более строгая реализация потребует определения манифестов записей Class-path, чтобы сделать модули EJB видимыми друг для друга и модули WAR.
Теперь, учитывая все вышесказанное, ваша конкретная проблема, скорее всего, одна из:
- класс в модуле lib, пытающийся получить доступ к классу в одном из модулей EJB или в одном из модулей WAR - вы поместили jar struts2 в каталог EAR/lib?
- класс в модуле EJB, пытающийся получить доступ к классу в одном из модулей WAR
Сказав все это, вы можете сделать свою жизнь намного проще, так как вы используете сервер JavaEE 7. Просто упакуйте все, включая EJB, в файл WAR. Скорее всего, вы не получаете никакой выгоды от создания и развертывания EAR