OpenLiberty耳朵Postgresql

问题描述

我想从Ear归档文件中加载postgresql jar文件
这是我的配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ear-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <includeLibInApplicationXml>true</includeLibInApplicationXml>
        <generateApplicationXml>true</generateApplicationXml>
        <defaultLibBundleDir>/lib</defaultLibBundleDir>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
            </manifest>
        </archive>
        <modules>
            <jarModule>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
            </jarModule>
            <webModule>
                <groupId>${project.groupId}</groupId>
                <artifactId>module-war</artifactId>
                <uri>/foodpicker.war</uri>
                <!-- Set custom context root -->
                <contextRoot>/</contextRoot>
            </webModule>
        </modules>
    </configuration>
</plugin>       

和server.xml:

<server description="Default Server">
    <featureManager>
        <feature>cdi-2.0</feature>
        <feature>beanValidation-2.0</feature>
        <feature>appSecurity-3.0</feature>
        <feature>managedBeans-1.0</feature>
        <feature>ejbLite-3.2</feature>
        <feature>localConnector-1.0</feature>
        <feature>microProfile-3.3</feature>
        <feature>jpa-2.2</feature>
        <feature>jwt-1.0</feature>
    </featureManager>

    <library id="project-libs">
        <fileset dir="lib" includes="*.jar"/> // <--- not loaded from ear file !!!
    </library>
    <dataSource jndiName="jdbc/jta-datasource" transactional="true">
        <jdbcDriver id="database-driver" libraryRef="project-libs"/>
        <properties databaseName="${database.name}" serverName="${database.hostname}" portNumber="${database.port}"
                    user="${database.username}" password="${database.password}"/>
    </dataSource>
    <basicRegistry id="basic" realm="BasicRealm"/>
    <httpSession securityIntegrationEnabled="false"/>
    <httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="8080" httpsPort="9443">
        <httpOptions http2="enabled"/>
    </httpEndpoint>
    <webContainer disableXPoweredBy="true"/>
    <applicationManager autoExpand="true"/>
    <applicationMonitor updateTrigger="mbean"/>
</server>     

这是耳朵文件的目录结构:

.
├── foodpicker.war
├── lib
│   └── org.postgresql-postgresql-42.2.12.jar
└── meta-inf
    ├── application.xml
    ├── MANIFEST.MF
    └── maven
        └── ir.moke.foodpicker
            └── module-ear
                ├── pom.properties
                └── pom.xml

如果我将<fileset>更改为文件系统上另一个目录的绝对路径,则应用程序加载并正常工作。但是我想让OpenLiberty Application Server从Ear文件中加载该库。

如何解决此问题?

解决方法

Liberty中服务器配置的数据源必须从服务器配置中定义的库中通过libraryRef加载JDBC驱动程序类。如果需要,这允许由连接池支持的数据源跨多个应用程序使用,而不必担心连接池是否正在将连接从正确的类加载器分发给每个相应的应用程序。因此,您无法以配置方式来实现它。

但是,有一种方法(由Java / Jakarta EE规范定义)可以在应用程序内部定义数据源,然后可以从应用程序中加载JDBC驱动程序类。

与其在server.xml中定义数据源,不如在您的Web组件(Servlet)中定义它

@DataSourceDefinition(name = "java:app/env/jdbc/jta-datasource",className = "org.postgresql.xa.PGXADataSource",transactional = true,url = "jdbc:postgresql://${database.hostname}:${database.port}/${database.name}",user = "${database.username}",password = "${database.password}")
public class MyServlet ...

您可以按以下方式查找数据源,

DataSource ds = InitialContext.doLookup("java:app/env/jdbc/jta-datasource");

您还可以定义对其的资源引用,就像任何服务器配置的数据源一样,

@Resource(name = "java:comp/env/jdbc/jta-datasource-ref",lookup = "java:app/env/jdbc/jta-datasource",shareable = true)
DataSource jtaDataSource;