java - 添加外部 jar 与 bean ( war 之外)

标签 java jakarta-ee cdi payara

我正在尝试在 war 文件之外加载 beans。目标是应该可以在不使用新的 war 文件的情况下更改 jar 文件。

我的 war 文件包含外部 jar 作为提供的依赖项:

        <dependency>
            <groupId>com.lube</groupId>
            <artifactId>foo</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>

我将 jar 文件添加到域目录 (domain/lib/applibs) 中的 applibs 文件夹中,并在部署过程中填写了库字段。

payara deployment

看起来没有从这个jar文件加载任何bean(不可能注入(inject)),但是可以使用该类。 (该类在当前类加载器中可用)。

如果我从 war 文件中向类中注入(inject)某些内容,我会收到以下异常 UnsatisfiedResolutionException:WELD-001334:带有限定符的类型 XXX 的依赖关系不满足

我使用的是 payara 4.1.2.174,但它也不适用于 payara 5。

主要问题是:是否可以在 war 之外加载bean(ejb/cdi)?我在网上没有找到任何好的解决方案。

P.S.:我无法使用微服务;)

编辑: war 文件包含 jar 文件。 jar 文件当前位于/lib/applibs 下的域中(我也测试了所有其他文件夹)

我执行此操作的命令如下 asadmin add-library --type app C:\library.jar

library.jar 仅包含一个 CDI bean

@Model
public class CdiBean {
    public void test() {
        System.out.println("It works!");
    }
}

和 beans.xml 文件。 (资源/META-INF - 我也在没有 META-INF 文件夹的情况下测试了它)

WAR 文件有一个尝试加载 Bean 的启动类。

@Singleton
@Startup
@TransactionManagement(value = javax.ejb.TransactionManagementType.BEAN)
public class AppStartup {
    @PostConstruct
    public void postConstruct() {
        try {
            System.out.println(CdiBean.class);
            CDI.current().select(CdiBean.class).get().test();
        } catch (Exception e) {
            throw new IllegalStateException(e.getMessage(), e);
        }
    }
}

war 部署后的输出为:

[2020-01-21T13:47:36.413+0100] [Payara 4.1] [INFO] [] [] [tid: _ThreadID=103 _ThreadName=admin-thread-pool::admin-listener(3)] [timeMillis: 1579610856413] [levelValue: 800] [[   class com.lube.CdiBean]]

[2020-01-21T13:47:36.474+0100] [Payara 4.1] [SEVERE] [] [javax.enterprise.system.tools.deployment.common] [tid: _ThreadID=103 _ThreadName=admin-thread-pool::admin-listener(3)] [timeMillis: 1579610856474] [levelValue: 1000] [[
  Exception while invoking class org.glassfish.ejb.startup.EjbApplication start method
javax.ejb.EJBException: javax.ejb.CreateException: Initialization failed for Singleton AppStartup
    ...
Caused by: javax.ejb.CreateException: Initialization failed for Singleton AppStartup
    at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:553)
    at com.sun.ejb.containers.AbstractSingletonContainer.access$000(AbstractSingletonContainer.java:82)
    at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:723)
    ... 72 more
Caused by: java.lang.IllegalStateException: WELD-001334: Unsatisfied dependencies for type CdiBean with qualifiers  
    ... 74 more
Caused by: org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type CdiBean with qualifiers  
    ... 102 more
]]

最佳答案

经过 3 天的测试,我找到了解决方案 - 终于:D 我没有找到任何解决方案,所以我在 payara github 存储库中搜索“applibs”,我发现了以下有趣的类(class)。 appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java

有一个名为 private void processBdasForAppLibs( ReadableArchive archive, DeploymentContext context ) 的方法,其中包含一个不错的 java 文档。

 // These are application libraries that reside outside of the ear.  They are usually specified by entries
    // in the manifest.
    // to test this put a jar in domains/domain1/lib/applibs and in its manifest make sure it has something like:
    //                           Extension-Name: com.acme.extlib
    // In a war's manifest put in something like:
    //                           Extension-List: MyExtLib
    //                           MyExtLib-Extension-Name: com.acme.extlib

当我发现我将以下插件添加到 jar 文件后:

            <plugin>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Extension-Name>com.lube</Extension-Name>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>

以及 war 文件中的以下内容

            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.3</version>
                <configuration>
                    <archive>
                        <manifestEntries>
                            <Extension-List>ExternalLib</Extension-List>
                            <ExternalLib-Extension-Name>com.lube</ExternalLib-Extension-Name>
                        </manifestEntries>
                    </archive>
                </configuration>
            </plugin>

之后,我构建了 jar 并将其添加到 domain/lib/applibs 中。比我部署了 war ,一切都按预期进行!

关于java - 添加外部 jar 与 bean ( war 之外),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59838431/

相关文章:

ajax - 如何将 @ConversationScoped 与 Ajax 请求一起使用?

java - Hibernate:禁用为 C3P0 创建自动测试表

java - 如何将java对象传递给mysql存储过程

java - 如何使用相机正确显示 3D 形状?

spring - Spring + Tomcat 什么时候不够强大?

java - JPA - 将一个实体更新/删除语句重定向到镜像表

java - 如果要注入(inject)的实例具有最终类,如何使用 InjectMocks

java - 从 VIM 编辑 .java 文件时运行 java 类的最简单方法

java - Struts 中的 Controller

java - 如何在 CDI 注入(inject)的字段中从父类(super class)转换为派生类?