Как добавить драйвер Postgres в Open Liberty?

Я реализую базовый REST API с помощью Micorprofile 3.2 и развертываю его с помощью Open Liberty.

сервер.xml,

<?xml version="1.0" encoding="UTF-8"?>
<server description="${project.name}">

    <featureManager>
        <feature>microProfile-3.2</feature>
        <feature>jpa-2.2</feature>
        <feature>jdbc-4.2</feature>
        <feature>jndi-1.0</feature>
    </featureManager>

    <httpEndpoint id="defaultHttpEndpoint"
                  host="*"
                  httpPort="8080"
                  httpsPort="9443"/>

    <webApplication location="${project.name}.war" contextRoot="/"/>
    <mpMetrics authentication="false"/>

    <dataSource id="DefaultDataSource"
                jndiName="jdbc/postgresql">
        <jdbcDriver jdbcDriverRef="postgresql-driver" libraryRef="postgresql-library"/>
        <properties.postgres serverName="localhost"
                             portNumber="5432"
                             databaseName="postgres"
                             user="postgres"
                             password="postgres"/>
    </dataSource>

    <jdbcDriver id="postgresql-driver"
                javax.sql.XADataSource="org.postgresql.xa.PGXADataSource"
                javax.sql.ConnectionPoolDataSource="org.postgresql.ds.PGConnectionPoolDataSource"
                libraryRef="postgresql-library"/>

    <library id="postgresql-library">
        <fileset id="PostgreSQLFileset" dir="${shared.resource.dir}/jdbc"
                 includes="postgresql-42.2.9.jar"/>
    </library>
</server>

мое постоянство.xml,

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence">

    <persistence-unit name="jpa-unit" transaction-type="JTA">
        <jta-data-source>jdbc/postgresql</jta-data-source>
    </persistence-unit>
</persistence>

Проблема в том, что каждый раз, когда я пытаюсь использовать EntityManager, я получаю следующую ошибку:

[INFO] [ERROR   ] CWWJP0015E: An error occurred in the org.eclipse.persistence.jpa.PersistenceProvider persistence provider when it attempted to create the container entity manager factory for the jpa-unit persistence unit. The following error occurred: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.5.v20191016-ea124dd158): org.eclipse.persistence.exceptions.EntityManagerSetupException
[INFO] Exception Description: Predeployment of PersistenceUnit [jpa-unit] failed.
[INFO] Internal Exception: javax.persistence.PersistenceException: CWWJP0013E: The server cannot locate the java:comp/DefaultDataSource data source for the jpa-unit persistence unit because it has encountered the following exception: javax.naming.NamingException [Root exception is java.sql.SQLNonTransientException: DSRA4000E: No implementations of [javax.sql.XADataSource, javax.sql.ConnectionPoolDataSource, javax.sql.DataSource, java.sql.Driver] are found for dataSource[DefaultDataSource] with library postgresql-library. The name or location of JDBC driver JAR files might be incorrect or inaccessible. Searched in: []. Searched under packages: [].].
[INFO] [ERROR   ] CWOWB1000E: A CDI error has occurred: CWNEN0030E: The server was unable to obtain an object instance for the java:comp/env/xx.xx.demo.micro.pq.infrastructure.infrastructure.EntityManagerProducer/entityManagerFactory reference.  The exception message was: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.5.v20191016-ea124dd158): org.eclipse.persistence.exceptions.EntityManagerSetupException
[INFO] Exception Description: Predeployment of PersistenceUnit [jpa-unit] failed.
[INFO] Internal Exception: javax.persistence.PersistenceException: CWWJP0013E: The server cannot locate the java:comp/DefaultDataSource data source for the jpa-unit persistence unit because it has encountered the following exception: javax.naming.NamingException [Root exception is java.sql.SQLNonTransientException: DSRA4000E: No implementations of [javax.sql.XADataSource, javax.sql.ConnectionPoolDataSource, javax.sql.DataSource, java.sql.Driver] are found for dataSource[DefaultDataSource] with library postgresql-library. The name or location of JDBC driver JAR files might be incorrect or inaccessible. Searched in: []. Searched under packages: [].].
[INFO] [ERROR   ] CWOWB1000E: A CDI error has occurred: CWNEN0030E: The server was unable to obtain an object instance for the java:comp/env/xx.xx.demo.micro.pq.infrastructure.infrastructure.EntityManagerProducer/entityManagerFactory reference.  The exception message was: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.7.5.v20191016-ea124dd158): org.eclipse.persistence.exceptions.EntityManagerSetupException
[INFO] Exception Description: Predeployment of PersistenceUnit [jpa-unit] failed.
[INFO] Internal Exception: javax.persistence.PersistenceException: CWWJP0013E: The server cannot locate the java:comp/DefaultDataSource data source for the jpa-unit persistence unit because it has encountered the following exception: javax.naming.NamingException [Root exception is java.sql.SQLNonTransientException: DSRA4000E: No implementations of [javax.sql.XADataSource, javax.sql.ConnectionPoolDataSource, javax.sql.DataSource, java.sql.Driver] are found for dataSource[DefaultDataSource] with library postgresql-library. The name or location of JDBC driver JAR files might be incorrect or inaccessible. Searched in: []. Searched under packages: [].].
[INFO] [WARNING ] CWMOT0009W: The OpenTracing exception mapper detected and is handling an unhandled exception from the JAX-RS application. 
[INFO]                                                                                                                java.lang.NullPointerException
[INFO]  at xx.xx.demo.micro.pq.infrastructure.infrastructure.EntityManagerProducer.createEntityManager(EntityManagerProducer.java:21)
[INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[INFO]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[INFO]  at java.lang.reflect.Method.invoke(Method.java:498)
[INFO]  at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:95)
[INFO]  at [internal classes]
[INFO]  at org.jboss.weldx.persistence.EntityManager$1152902288$Proxy$_$$_WeldClientProxy.getCriteriaBuilder(Unknown Source)
[INFO]  at xx.xx.demo.micro.pq.domain.ProductRepository.findAll(ProductRepository.java:42)
[INFO]  at xx.xx.demo.micro.pq.domain.ProductRepository$Proxy$_$$_WeldClientProxy.findAll(Unknown Source)
[INFO]  at xx.xx.demo.micro.pq.application.ProductResource.getAllProduct(ProductResource.java:54)
[INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[INFO]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[INFO]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[INFO]  at java.lang.reflect.Method.invoke(Method.java:498)
[INFO]  at com.ibm.ws.jaxrs20.cdi.component.JaxRsFactoryImplicitBeanCDICustomizer.serviceInvoke(JaxRsFactoryImplicitBeanCDICustomizer.java:304)
[INFO]  at [internal classes]

Я создаю EntityManager следующим образом:

  @(unitName = "jpa-unit")
  private EntityManagerFactory entityManagerFactory;

  @Produces
  @RequestScoped
  public EntityManager createEntityManager() {
    return entityManagerFactory.createEntityManager();
  }

Я не очень понимаю, почему сюда заглядывает открытая свобода: Searched in: []. Searched under packages: [].].

РЕДАКТИРОВАТЬ: добавить pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>xx.xxx</groupId>
    <artifactId>demo-micro-pq</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <openliberty.maven.version>3.1</openliberty.maven.version>
        <final.name>demo-micro-pq</final.name>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <openliberty.version>[19.0.0.9,)</openliberty.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <version.javaee>8.0.1</version.javaee>
        <version.slf4j>1.7.28</version.slf4j>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.eclipse.microprofile</groupId>
            <artifactId>microprofile</artifactId>
            <version>3.2</version>
            <type>pom</type>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>${version.javaee}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.4.10.Final</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${version.slf4j}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${version.slf4j}</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>demo-micro-pq</finalName>
    </build>
    <profiles>
        <profile>
            <id>liberty</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.openliberty.tools</groupId>
                        <artifactId>liberty-maven-plugin</artifactId>
                        <version>${openliberty.maven.version}</version>
                        <executions>
                            <execution>
                                <id>package-server</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>create</goal>
                                    <goal>install-feature</goal>
                                    <goal>deploy</goal>
                                    <goal>package</goal>
                                </goals>
                                <configuration>
                                    <outputDirectory>target/wlp-package</outputDirectory>
                                </configuration>
                            </execution>
                        </executions>
                        <configuration>
                            <include>runnable</include>
                            <serverName>${final.name}</serverName>
                            <bootstrapProperties>
                                <project.name>${final.name}</project.name>
                                <jwt.issuer>https://server.example.com</jwt.issuer>
                            </bootstrapProperties>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-dependency-plugin</artifactId>
                        <version>3.1.1</version>
                        <executions>
                            <execution>
                                <id>copy</id>
                                <phase>package</phase>
                                <goals>
                                    <goal>copy</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>org.postgresql</groupId>
                                    <artifactId>postgresql</artifactId>
                                    <version>42.2.9</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                            <outputDirectory>liberty/wlp/usr/shared/resources</outputDirectory>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

person max    schedule 04.02.2020    source источник
comment
Вы уверены, что файл postgresql-42.2.9.jar действительно попадает в каталог /opt/ol/wlp/lib? Если вы (обычно) используете Maven/Gradle и/или Docker, в вашей сборке может возникнуть проблема с копированием этого файла на место. (Если это так, возможно, покажите свой файл сборки, например, pom.xml, и покажите команду сборки, которую вы используете).   -  person Scott Kurz    schedule 04.02.2020
comment
я добавил помпу   -  person max    schedule 04.02.2020
comment
Я не вижу ничего, копирующего JAR postgresql на место. Например. в в этом примере я использую dependency:copy-dependencies, чтобы скопировать драйвер JDBC на место, привязав его к фазе package. Я не говорю, что это единственный способ, и на самом деле у нас есть открытый вопрос, где мы обсуждаем способы улучшения liberty-maven-plugin, чтобы, возможно, сделать некоторые из этих копий зависимостей для вас. Но как вы думали решить эту часть проблемы?   -  person Scott Kurz    schedule 04.02.2020
comment
Хотя это и не связано с проблемой, которую вы видите, следует указать, что jdbcDriverRef не является допустимым атрибутом в jdbcDriver, поэтому эта часть вашей конфигурации игнорируется.   -  person njr    schedule 04.02.2020
comment
я следил за этим комментарием, но все равно получаю ту же ошибку вместо Searched in: []. Searched under packages: [].]. я получаю: Searched in: []. Searched under packages: [org.postgresql.ds].].. спасибо за помощь кстати   -  person max    schedule 04.02.2020
comment
Начиная с версии 3.3 модуля Liberty Maven Plug- в есть параметр copyDependencies. См. мой ответ здесь.   -  person ltlBeBoy    schedule 13.07.2021


Ответы (1)


Плагин зависимостей 'outputDirectory' должен соответствовать каталогу server.xml

Вам необходимо согласовать конфигурацию вашего сервера с местом, куда вы копируете зависимость в своей сборке Maven.

(Похоже, ваша проблема заключается в том, что у вас есть дополнительный подкаталог «jdbc» в конфигурации вашего сервера по сравнению с местом, в которое вы копируете из своей сборки Maven).

E.g.

сервер.xml

<server>
    <library id="postgresql-library">
        <fileset id="PostgreSQLFileset" dir="${shared.resource.dir}/jdbc"
                 includes="postgresql-42.2.9.jar"/>
    </library>
</server>

должен указывать на тот же каталог, что и:

пом.xml

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
                <configuration>
                   <outputDirectory>${project.build.directory}/liberty/wlp/usr/shared/resources/jdbc</outputDirectory>

Последующая записка

Обратите внимание, что сейчас открыта проблема, в которой мы обсуждаем разные идеи по добавлению поддержка в самом liberty-maven-plugin для копирования зависимостей на место.

person Scott Kurz    schedule 04.02.2020
comment
это сработало. большое тебе спасибо. Да, я поместил драйвер в неправильный пакет. Не уловил :D - person max; 06.02.2020