How to copy external dependency to Open Liberty during maven build - maven

UPDATE - July 2021:
While the accepted answer using the dependency plugin was the best solution at the time, the answer from #ltlBeBoy leverages the 'copyDependencies' support since added to liberty-maven-plugin. Using 'copyDependencies' is usually a better solution, since it is integrated into the "dev mode" loop and less verbose (at the expense of supporting fewer options than the dependency plugin).
ORIGINAL QUESTION
I need to copy derby.jar into Open Liberty shared directory
${project.build.directory}/liberty/wlp/usr/shared/resources/. I have the following setup in the pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-derby-dependency</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>derby</includeArtifactIds>
<outputDirectory>${project.build.directory}/liberty/wlp/usr/shared/resources/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
and the part for configuring open liberty
<plugin>
<groupId>net.wasdev.wlp.maven.plugins</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>${openliberty.maven.version}</version>
<executions>
<execution>
<id>package-server</id>
<phase>package</phase>
<goals>
<goal>create-server</goal>
<goal>install-apps</goal>
<goal>package-server</goal>
</goals>
<configuration>
<outputDirectory>target/wlp-package</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<assemblyArtifact>
<groupId>io.openliberty</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>${openliberty.version}</version>
<type>zip</type>
</assemblyArtifact>
<configFile>src/main/liberty/config/server.xml</configFile>
<appArchive>${project.build.directory}/${final.name}.war</appArchive>
<packageFile>${project.build.directory}/${final.name}.jar</packageFile>
<include>runnable</include>
<serverName>${final.name}</serverName>
<installAppPackages>project</installAppPackages>
<configDirectory>${project.basedir}/src/main/liberty/server</configDirectory>
<bootstrapProperties>
<project.name>${final.name}</project.name>
<jwt.issuer>https://server.example.com</jwt.issuer>
</bootstrapProperties>
</configuration>
</plugin>
With this setup I have to execute mvn package goal twice. It looks like that when liberty-maven-plugin is executed the ${project.build.directory}/liberty/wlp/usr/shared/resources/ folder is removed if there is no liberty server under liberty/wlp/.
Maven LOG:
[INFO] --- maven-dependency-plugin:2.10:copy-dependencies (copy-derby-dependency) # account ---
[INFO] Copying derby-10.15.1.3.jar to /Users/anton/github/account/target/liberty/wlp/usr/shared/resources/derby-10.15.1.3.jar
and after it
[INFO] --- liberty-maven-plugin:2.2:create-server (package-server) # account ---
[INFO] CWWKM2110I: Uninstalling: /Users/anton/github/account/target/liberty/wlp.
Can someone please help me with this?

Here's an example from the Session Cache guide from OpenLiberty.io showing how this can be done. The example is getting a hazelcast.jar, but it could be used for any jar hosted in maven.
https://github.com/OpenLiberty/guide-sessions/blob/master/finish/pom.xml
<!-- package hazelcast.jar -->
<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>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>${hazelcast.version}</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/liberty/wlp/usr/shared/resources</outputDirectory>
<destFileName>hazelcast.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/liberty/wlp/usr/shared/resources</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</plugin>

As already stated in my other answer, starting from version 3.3 of the Liberty Maven Plug-in there is a copyDependencies parameter:
pom.xml
<plugins>
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.3.4</version>
<configuration>
<!-- Usually best to add configuration at the plugin level rather than trying to configure particular executions -->
<copyDependencies>
<dependencyGroup>
<!-- Relative to server config directory -->
<location>lib/global/jdbc</location>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
</dependency>
</dependencyGroup>
</copyDependencies>
</configuration>
...
server.xml
...
<!-- Derby Library Configuration -->
<library id="derbyJDBCLib">
<fileset dir="${server.config.dir}/lib/global/jdbc" includes="derby*.jar"/>
</library>
...
See documentation for further details.

Related

Checkstyle checkstyle-checker.xml gets overriden when multiple configs are used

I need to separate the checkstyle plugin configs for production and test source code.
I managed to do it (see the config bellow), but there is 'checkstyle-checker.xml' file which is always overriden and stays in the root of the target directory.
Is there a way to move it to /target/checkstyle directory?
Is there a way to separate it between prod and test source code?
<plugin>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<failOnViolation>${maven-checkstyle-plugin.failOnViolation}</failOnViolation>
<logViolationsToConsole>${maven-checkstyle-plugin.logViolationsToConsole}</logViolationsToConsole>
<violationSeverity>warning</violationSeverity>
<linkXRef>true</linkXRef>
<skip>${maven-checkstyle-plugin.skip}</skip>
</configuration>
<executions>
<execution>
<id>checkstyle-validate</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<sourceDirectories>${project.build.sourceDirectory}</sourceDirectories>
<includeTestSourceDirectory>false</includeTestSourceDirectory>
<configLocation>/checkstyle/checkstyle.xml</configLocation>
<outputFile>${project.build.directory}/checkstyle/checkstyle-result.xml</outputFile>
<cacheFile>${project.build.directory}/checkstyle/checkstyle-cache</cacheFile>
</configuration>
</execution>
<execution>
<id>checkstyle-validate-test</id>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<sourceDirectories/>
<testSourceDirectories>${project.build.testSourceDirectory}</testSourceDirectories>
<includeTestSourceDirectory>true</includeTestSourceDirectory>
<configLocation>/checkstyle/checkstyle-test.xml</configLocation>
<outputFile>${project.build.directory}/checkstyle/checkstyle-result-test.xml</outputFile>
<cacheFile>${project.build.directory}/checkstyle/checkstyle-cache-test</cacheFile>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>${maven-checkstyle-plugin.checkstyle.rules.version}</version>
</dependency>
</dependencies>
</plugin>
This file appears to be generated by maven-checkstyle-plugin as seen at https://github.com/apache/maven-checkstyle-plugin/blob/6d229a74b4a7eb2efc5fce287d932f6b5c250647/src/main/java/org/apache/maven/plugins/checkstyle/exec/DefaultCheckstyleExecutor.java#L733
Looking at https://github.com/apache/maven-checkstyle-plugin/blob/6d229a74b4a7eb2efc5fce287d932f6b5c250647/src/main/java/org/apache/maven/plugins/checkstyle/exec/DefaultCheckstyleExecutor.java#L765 it appears there is no way to override it's location and it will always go into the project's build directory.
I am not sure what purpose this file plays in the work the plugin does as this is not part of the base checkstyle library.

JPMS/Jigsaw keycloak-spring-boot-starter (invalid module name & ResolutionException)

the Java 11 maven application is modularized with JPMS/Jigsaw.
Problem 1: keycloak-spring-boot-2-adapter invalid module-name '2'
Solution 1: Renamed by maven plugin with removed "-2". But I'm not sure if this is a good solution.
<plugin>
<!-- for copying dependent libraries to folder lib -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>../lib</outputDirectory>
<excludeGroupIds>com.xyz</excludeGroupIds>
<excludeArtifactIds>keycloak-spring-boot-2-adapter</excludeArtifactIds>
</configuration>
</execution>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifacItem>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-2-adapter</artifactId>
<overWrite>true</overWrite>
<outputDirectory>../lib</outputDirectory>
<destFileName>keycloak-spring-boot-adapter-9.0.2.jar</destFileName>
</artifacItem>
</artifactItems>
<!-- other configurations here -->
</configuration>
</execution>
</executions>
</plugin>
Problem 2: keycloak.spring.boot.adapter and keycloak.spring.boot.adapter.core have the same package name.
java.lang.module.ResolutionException: Modules keycloak.spring.boot.adapter and keycloak.spring.boot.adapter.core export package org.keycloak.adapters.springboot to module org.yaml.snakeyaml
Solution 2: ?
Thanks for your help and best regards,
Pierre
There is a ticket (KEYCLOAK-12499) with two sub tasks describing the two problems you're facing: KEYCLOAK-9072 (Problem 1) and KEYCLOAK-9073 (Problem 2).
The first problem is a trivial one, both from your perspective as from the perspective of the maintainers of Keycloak.
The second problem however requires more work because two (actually three) artifacts are sharing the same package and are exporting it when they are used as automatic modules (because automatic modules export all of their packages).
Exporting the same package from more than one module is not allowed however (http://openjdk.java.net/projects/jigsaw/spec/reqs/#non-interference).
The three artifacts involved in this problem are keycloak-spring-boot-adapter-core, keycloak-spring-boot-adapter and keycloak-spring-boot-2-adapter. The adapter-core artifact works somewhat like an abstract implementation for the two other modules and provides package private classes and methods which are used by the other two modules.
The emphasized text is the core of the second problem: sharing a package across different artifacts works for classic Java without modules, but the module system blocks this because it breaks encapsulation.
Solving the second problem requires you to make copies of keycloak-spring-boot-adapter-core and keycloak-spring-boot-2-adapter and adjust their code — at least until there is a fix for the official artifacts.
A solution for problem 2 is building an own automatic module.
Create a new module and add a POM with the following build plugins and dependency.
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-2-adapter</artifactId>
<version>9.0.2</version>
<exclusions>
<exclusion>
<groupId> org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
...
</exclusions>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
</plugin>
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>../mods</outputDirectory>
<archive>
<manifestEntries>
<Automatic-Module-Name>modulename</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>install-external</id>
<phase>install</phase>
<configuration>
<file>${project.basedir}/../mods/modulename-1.0-SNAPSHOT.jar</file>
<repositoryLayout>default</repositoryLayout>
<groupId>com.xyz.assembly</groupId>
<artifactId>modulename</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
<goals>
<goal>install-file</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You can add the dependency via com.xyz.assembly as groupID to other modules.
But keep attention!
It will use the module-info.java of log4j if you don't exclude it in this assembly module.

Auto deploy maven project war file in company's server

I have created a maven project in netbeans and there i manually build a war file and upload to server.
My pom file only contains:
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
...
<dependency>
<dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-maven-plugin</artifactId>
<version>4.0.0-release</version>
<configuration>
<log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
<!--<plugin>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>2.9.0</version>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbcDriver>com.mysql.jdbc.Driver</jdbcDriver>
<jdbcUrl>jdbc:mysql://localhost:3306/login</jdbcUrl>
<jdbcUser>root</jdbcUser>
<packageName>com.titas.model</packageName>
<targetFolder>${project.basedir}/target/generated-sources/java</targetFolder>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
</plugin>-->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.jdo.JDOAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now i want to auto deploy war file in company's server whenever i will build in netbeans.
Is there any tag to auto deploy in server in pom.xml? Like if i use any plugin where i will specify my server folder war file will auto deploy there and replace previous one.
Thanks in advance!!
I don't have experience deploying to Tomcat specifically, and apparently it's different based on the version.
Tomcat 6/7
For Tomcat 6 replace "tomcat7" with "tomcat6" in the following lines.
Use the tomcat7-maven-plugin by putting this in the <build><plugins> section of your pom.xml:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<url>http://www.example.com:1234/mymanager</url>
</configuration>
</plugin>
Obviously change the url to match the URL of the server/manager you're trying to deploy to. If you need to specify credentials add a <server>servername</server> tag to the configuration block and put this in your maven settings.xml (under path <settings><servers>):
<server>
<id>servername</id>
<username>myusername</username>
<password>mypassword</password>
</server>
For other configuration changes see the plugin page linked above.
Once it's configured you should be able to run mvn package tomcat7:deploy to deploy to your server. Other maven goals are here.
Tomcat 8
The best I'm finding is this question: Tomcat 8 integration with Maven
The accepted answer uses the cargo-maven2-plugin, but looking at how it's configured I don't think that will go to a remote machine.
Alternately you can try the tomcat7 plugin as detailed above, I did see this blog post that suggests it works for 8 too.

How do I set up datasource for JBoss plugin using Maven to run tests with Arquillian?

I'm trying to make work arquillian tests with jboss managed server and IBM DB2 database.
For now I'm stuck on creating datasource. Since JBoss is unpacked on each run, I'm trying to add driver and datasource configuration into pom.xml in order to Maven take care of creating proper configurations on JBoss and resulting section looks like this:
<profile>
<id>arquillian-jboss-managed</id>
<build>
<plugins>
<!-- JBoss server itself -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>process-test-classes</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-dist</artifactId>
<version>7.1.1.Final</version>
<type>zip</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<!-- adding datasource -->
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<executions>
<execution>
<id>deploy-driver</id>
<phase>process-test-classes</phase>
<!-- groupId and artifactId aren't global, I've got jar on defined path -->
<configuration>
<groupId>db2</groupId>
<artifactId>db2cc</artifactId>
<name>db2jcc4.jar</name>
</configuration>
<goals>
<goal>deploy-artifact</goal>
</goals>
</execution>
<execution>
<id>add-datasource</id>
<phase>process-test-resources</phase>
<configuration>
<address>subsystem=datasources,data-source=MyDataSource</address>
<properties>
<connection-url>jdbc:db2://host:port/database</connection-url>
<jndi-name>MyDataSource</jndi-name>
<enabled>true</enabled>
<pool-name>MyDataSource</pool-name>
<user-name>db2inst1</user-name>
<password>pass</password>
<driver-name>db2jcc4.jar</driver-name>
</properties>
</configuration>
<goals>
<goal>add-resource</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
Yet I've got an error:
Failed to execute goal
org.jboss.as.plugins:jboss-as-maven-plugin:7.4.Final:add-resource
(add-datasource) on project testrunner: Could not execute goal
add-resource. Reason: I/O Error could not execute operation '{
"address" => [], "operation" => "read-attribute", "name" =>
"launch-type" }': java.net.ConnectException: JBAS012144: Could not
connect to remote://localhost:9999. The connection timed out
I guess the problem is JBoss isn't started at the moment Maven tries to apply configuration parameters or simply doesn't listen to required port.
Any help is greatly appreciated
Thanks in advance
Fixing this problem was as simple as adding start and shutdown goals to jboss-as-maven-plugin executions before and after other configuration:
<execution>
<id>start-server</id>
<phase>process-test-classes</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<!-- copying driver and datasource here -->
<execution>
<id>shutdown-server</id>
<phase>process-test-classes</phase>
<goals>
<goal>shutdown</goal>
</goals>
</execution>
Also this start goal downloads it's own JBoss instance if one is not provided. So this part is not needed any more:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<!-- skipped -->
</plugin>

Reference resources from a test-jat artifact

I have two artifact:
artifact-A: contains resources in src/test/resources/
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
artifact B: uses resources from artifact A
<dependency>
<groupId>com.xxxx.yyy</groupId>
<artifactId>artifact-A</artifactId>
<version>3.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
The problem is that the resources are never extracted in the project artifact-B.
How can I do that ?
If you define a dependency like this the used jar will never be extracted cause it will be put on the classpath during compilation etc. This means to access the resources from artifact-A you need to access them via the classpath.
In artifact-B, I used the maven-dependency-plugin to extract resources from the test-jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>resource-dependencies</id>
<phase>process-test-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>artifact-A</includeArtifactIds>
<includes>**/db-test/*</includes>
<outputDirectory>${project.build.testOutputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

Resources