mavenjakarta-eederbyopen-libertyliberty-maven-plugin

Configuring Apache Derby dependency in Open Liberty Maven project


I'm trying to connect a Derby database with my Open Liberty application, but I can't get it to work. I don't think I understood the process correctly. Here's what I did.

I downloaded db-derby-10.15.2.0-bin.tar.gz from the Derby website and extracted it into the root folder of my project.

I put the following into my server.xml file:

<!-- Derby Library Configuration -->
    <library id="derbyJDBCLib">
        <fileset dir="db-derby-10.15.2.0-bin/lib" />
    </library>

    <!-- Datasource Configuration -->
    <dataSource id="derbyjpadatasource" jndiName="jdbc/my-project">
        <jdbcDriver libraryRef="derbyJDBCLib" />
        <properties.derby.embedded databaseName="myDB" createDatabase="create" />
    </dataSource>

Created a persistence.xml file in my META-INF folder:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
             xmlns="http://xmlns.jcp.org/xml/ns/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_2.xsd">
    <persistence-unit name="jpa-unit" transaction-type="JTA">
        <jta-data-source>jdbc/my-project</jta-data-source>
        <properties>
            <property name="jakarta.persistence.schema-generation.database.action"
                      value="create"/>
            <property name="jakarta.persistence.schema-generation.scripts.action"
                      value="create"/>
            <property name="jakarta.persistence.schema-generation.scripts.create-target"
                      value="createDDL.ddl"/>
        </properties>
    </persistence-unit>
</persistence>

And edited my pom.xml file so it contains this:

<plugin>
                <groupId>io.openliberty.tools</groupId>
                <artifactId>liberty-maven-plugin</artifactId>
                <version>3.7.1</version>
                <configuration>
                    <copyDependencies>
                        <location>${project.build.directory}/liberty/wlp/usr/shared/resources</location>
                        <dependency>
                            <groupId>org.apache.derby</groupId>
                            <artifactId>derby</artifactId>
                        </dependency>
                    </copyDependencies>
                </configuration>
</plugin>

The project compiles and runs, but any operations with persistent object result in errors. This is one of the warnings I see when running the server:

DSRA4000E: No implementations of org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource40
for dataSource [derbyjpadatasource] with library derbyJDBCLib were found.
The name or location of the JDBC driver JAR files may be incorrect
or inaccessible. Searched in: []. Searched in packages: [org.apache.derby.jdbc].

EDIT: New error message after Scott Kurz's suggestion:

DSRA4000E: No implementations of 
org.apache.derby.jdbc.EmbeddedConnectionPoolDataSource40 were 
found for dataSource[derbyjpadatasource] with the library 
derbyJDBCLib. The name or location of the JDBC driver JAR files 
may be incorrect or inaccessible. Searched in 
[/home/(my_usr)/Desktop/Projects/proj1/target/liberty/
wlp/usr/shared/resources/derby-10.15.2.0.jar, 
/home/(my_usr)/Desktop/Projects/proj1/target/liberty/
wlp/usr/shared/resources/derbyshared-10.15.2.0.jar]. Searched in 
packages: [org.apache.derby.jdbc].

Solution

  • NOTE:

    The Apache Derby dependency packages seem to have been restructured around the 10.14.x -> 10.15.x timeframe, so the exact dependency set could be a bit different depending on the exact version used. Much of the pom.xml and server.xml config in this answer should work on both sides of that change, but if it doesn't work check the exact dependency list needed for the specific version of Derby you're using.

    copyDependencies in liberty-maven-plugin

    The idea behind the copyDependencies function in the liberty-maven-plugin is that you can have the plugin copy the dependency into place just without having to separately download, store, and then worry about copying this dependency JAR into the right location.

    So if you had:

    pom.xml

           <!-- In the dependencies section -->
            <dependency>
                <groupId>org.apache.derby</groupId>
                <artifactId>derby</artifactId>
                <version>10.15.2.0</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.derby</groupId>
                <artifactId>derbytools</artifactId>
                <version>10.15.2.0</version>
                <scope>provided</scope>
            </dependency>
    
             ...
    
           <!-- plugin configuration in build/plugins -->
            <groupId>io.openliberty.tools</groupId>
            <artifactId>liberty-maven-plugin</artifactId>
            <version>3.7.1</version>
            <configuration>
               <copyDependencies>
                <location>${project.build.directory}/liberty/wlp/usr/shared/resources</location>
                <dependency>
                 <groupId>org.apache.derby</groupId>
                 <!-- Selects all artifacts under this groupId -->
                 <artifactId>*</artifactId>
                </dependency>
              </copyDependencies>
            </configuration>
    

    You could combine this with server.xml configuration:

    server.xml

      <library id="derbyJDBCLib">
        <fileset dir="${shared.resource.dir}/" includes="derby*.jar" />
      </library>
    

    ADDITIONAL LINKS

    1. You can see this in action in our JPA guide sample at: https://openliberty.io/guides/jpa-intro.html

    2. Open Liberty has a convenient mechanism for validating a connection to a database. It can be helpful to validate this independently of any application (JDBC, JPA, etc.) code at the more basic level of server configuration.