简体   繁体   中英

Add External jar with beans (outside the war)

I am trying to load beans outside a war file. The goal is that is should be possible to change the jar file without a new war file.

My war file includes the external jar as a provided dependency:

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

I added the jar file into the applibs folder in the domain directory (domain/lib/applibs) and filled out the library field during the deployment.

payara部署

It seems that no beans are loaded from this jar file (injection is not possible), but it is possible to use the class. (the class is available in the current classloader).

If i am injecting something in a class from the war file i am getting following exception UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type XXX with qualifiers

I am using payara 4.1.2.174, but it doesn't work with payara 5 too.

The main question is: Should it be possible to load beans (ejb/cdi) outside the war? I don't find any good solution in the web.

PS: I can not use microservices;)

Edit: The war file does not contain the jar file. The jar file is currently located in the domain under /lib/applibs ( I tested all other folders too )

The command how i did that was the following asadmin add-library --type app C:\library.jar

The library.jar contains only one CDI bean

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

and the beans.xml file. (resources/META-INF - I tested it without the META-INF folder too)

The WAR file has a startup class which tries to load the 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);
        }
    }
}

The output after the deployment of the war is:

[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
]]

After 3 days of testing i found a solution - FINALLY:DI didn't find any solution so i searched in the payara github repo for "applibs" and i found following interessing class. appserver/web/weld-integration/src/main/java/org/glassfish/weld/DeploymentImpl.java

There is a method called private void processBdasForAppLibs( ReadableArchive archive, DeploymentContext context ) with a nice java doc.

 // 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

After i found that i added following plugin to the jar file:

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

and the following to the war file

            <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>

After that i build the jar and added it to the domain/lib/applibs . Than i deployed the war and everything works as expected!

  • You can combine multiple wars into single ear and run it.
  • Or it might be possible to use add-library command. It was available for GlassFish Server , it is available for Payara Micro . I believe there should be such functionality (I could find it for Payara Server though).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM