2

I am implementing a basic REST API with Micorprofile 3.2 and deploying it with Open Liberty.

The server.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>

my persistence.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>

The problem is everytime i try to use a EntityManager i get the following error:

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

I create the EntityManager the following way:

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

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

I dont really understand why open liberty looks in here: Searched in: []. Searched under packages: [].].

EDIT: add 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>
max
  • 45
  • 1
  • 5
  • 1
    Are you sure the "postgresql-42.2.9.jar" file is really ending up in the "/opt/ol/wlp/lib" directory? If you're (typically) using Maven/Gradle and/or Docker your build may have an issue copying this file into place. (If so, maybe show your build file, e.g. pom.xml and show the build command you're using). – Scott Kurz Feb 04 '20 at 13:36
  • i added the pom – max Feb 04 '20 at 13:42
  • 1
    I don't see anything copying the postgresql JAR into place. E.g. in [this](https://github.com/scottkurz/my-test-jdbc-appsody-binary/blob/93dd692b82afade9f2b08fbb584a81ee3e51de7a/a1-appsody-war/pom.xml#L189-L208) example I'm using `dependency:copy-dependencies` to copy my JDBC driver into place, binding this to the `package` phase. I'm not saying this is the only way, and in fact, we have an open issue now where we're discussing ways to enhance `liberty-maven-plugin` to possibly do some of this dependency copying for you. But how had you thought you'd solve this part of the problem? – Scott Kurz Feb 04 '20 at 14:22
  • 1
    Although unrelated to the problem you are seeing, it should be pointed out that jdbcDriverRef is not a valid attribute on jdbcDriver, so that part of your configuration is being ignored. – njr Feb 04 '20 at 14:32
  • i followed [this](https://stackoverflow.com/a/58065650/11922661) comment, but i still get the same error instead of `Searched in: []. Searched under packages: [].].` i get: `Searched in: []. Searched under packages: [org.postgresql.ds].].`. thank you for the help btw – max Feb 04 '20 at 19:43
  • Starting from [version 3.3](https://github.com/OpenLiberty/ci.maven/releases/tag/liberty-maven-3.3) of the Liberty Maven Plug-in there is a copyDependencies parameter. Se my answer [here](https://stackoverflow.com/a/68369132/5223047). – ltlBeBoy Jul 13 '21 at 20:48

1 Answers1

2

Dependency plugin 'outputDirectory' must match server.xml directory

You need to align your server config with the location you copy the dependency to in your Maven build.

(Your problem seems to be you have an extra 'jdbc' subdir in your server config, compared to the location you're copying into from your Maven build).

E.g.

server.xml

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

should point to the same directory as:

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

Follow-up note

Note there is an open issue now where we're discussing different ideas to add support into the liberty-maven-plugin itself for copying dependencies into place.

Scott Kurz
  • 4,985
  • 1
  • 18
  • 40
  • 2
    it worked. thank you very much. Yeah I put the driver in the wrong package. Didnt catch that :D – max Feb 06 '20 at 05:58