I'm trying to run a Java program with Maven on the commandline, but it is not putting the correct entries on the classpath. If I run the program in IntelliJ (which has Maven support), the classpath has 80 or so entries including my project's jar dependencies, the compile program classes, and the resources from src/main/resources. If I run the program with mvn exec:java, I only get one entry for apache-maven-3.0.4/boot/plexus-classworlds-2.4.jar. There are no references to plexus in my entire project tree. Where is this entry coming from and why are the other expected classpath entries not there?
Maven version: Apache Maven 3.0.4 (r1232337; 2012-01-17 00:44:56-0800)
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>MyProject</artifactId>
<version>SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- lots of dependencies -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<executable>${env.JAVA_HOME}/bin/javac</executable>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>${basedir}/src/assembly/assembly.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<mainClass>com.example.MyApp</mainClass>
<executable>${env.JAVA_HOME}/bin/java</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>
By default, the exec:java uses the 'runtime' scope, which will not bring your dependencies set with the 'compile' scope.
You can use:
exec:java -Dexec.classpathScope="compile"
To include the compile dependencies (not 100% sure about the -D syntax, but the variable is exec.classpathScope for sure).
This should do the trick.
If you need more info/options, the plugin page has some options listed: http://mojo.codehaus.org/exec-maven-plugin/java-mojo.html
I don't know about Plexus (I would guess it is a dependency of the Exec Maven Plugin?) , but try running with debugging turned on: mvn exec:java -X and it should be more clear that your dependencies are being added to the classpath:
....
[DEBUG] Invoking : com.example.MyApp.main()
[DEBUG] Plugin Dependencies will be excluded.
[DEBUG] Project Dependencies will be included.
[DEBUG] Collected project artifacts [log4j:log4j:jar:1.2.16:compile, commons-lang:commons-lang:jar:2.6:compile]
[DEBUG] Collected project classpath [C:\MyProject\target\classes]
[DEBUG] Adding to classpath : file:/C:/MyProject/target/classes/
[DEBUG] Adding project dependency artifact: log4j to classpath
[DEBUG] Adding project dependency artifact: commons-lang to classpath
....
You should see lots of the "Adding project dependency artifact" messages.
Related
I have a multi module maven project wie quarkus modules and some custom libraries which are local maven repositories (so they can be used by the other maven projects/modules). However, so that local maven repositories are recognizable und usable by your other local maven projects, you have to manually index them for some reason. I.e. add a config like this for quarkus index to the application.properties of the project including the local maven repo dependency:
quarkus.index-dependency.<index-name>.group-id = <group-id-of-local-maven-repo>
quarkus.index-dependency.<index-name>.artifact-id = <artifact-id-of-local-maven-repo>
The problem is, this causes issues for me becausse if you have 3 layers of project dependencies, say:
Project A (custom local maven repo library)
Project B (custom local maven repo library, includes Project A dependency)
application.properties (indexing Project A library dependency)
Project C (Local maven project for an end product, includes Project B
library dependency - and through it indirectly Project A).
application.properties (indexing Project B library dependency and config for datasources or other app related things)
Then when you generate an uber-jar (fat jar) of Project C for deployment, it for some reason uses application.properties of Project B in the packaged jar, instead of from the project which im building (Project C). Thus, the app is missing key configs and does not work. Maven seems to use an inverse priority here, which i dont know if thats a bug or not. When i asked about this, i was simply told that:
"My dependencies should not have application.properties".
I tried to find a way to prevent manual indexing via application.properties and found the maven jandex plugin - which is supposed to generate an index. The next problem is, this seems to only work in some projects but not in others in the dependency hierarchy, resulting in the same situation as before, and i don't understand why. This is the pom.xml config for the plugin i have included in all 3 projects (the entire pom.xml for all is too long, so let me know if you need more info):
<properties>
...
<jandex.skip>false</jandex.skip>
...
</properties>
...
<build>
...
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.0.5</version>
<inherited>true</inherited>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
<configuration>
<skip>${jandex.skip}</skip>
</configuration>
</plugin>
...
The odd thing is, this works to the extend that i no longer have to index Project B library dependency in Project C application.properties, but Project B library dependency still has to manually index Project A library dependency - thus rendering the entire exercise futile. Project C having an application.properties was never the issue, and is obviously needed. Project B still requires a properties file to point to Project A now, how do i solve this?
I have a parent module POM in the root folder containing all these projects, over which this maven jandex dependency is distributed to all modules, so it looks like this:
Maven parent module (contains all dependencies and versions used by all project sub modules)
Project A (custom local maven library repo), own pom.xml with inheritance from parent module
Project B (custom local maven library repo, includes Project A library), own pom.xml with inheritance from parent module
application.properties - Indexes Project A dependency manually, this is the problematic one which needs to go!
Project C (Local maven project for REST API etc., includes Project B library), own pom.xml with inheritance from parent module
pom.xml (parent module POM, containing maven jandex dependepency among others)
Edit: One of the projects, "entity", where all the database access objects are stored, does not run the jandex plugin during mvn clean install. This is the POM of the project:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.compamny.project</groupId>
<artifactId>entity</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
<version>2.16.1.Final</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-validator</artifactId>
<version>2.16.1.Final</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-reactive-jackson</artifactId>
<version>2.16.1.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>2.13.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.smallrye/jandex-maven-plugin -->
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<plugin>
<groupId>io.smallrye</groupId>
<artifactId>jandex-maven-plugin</artifactId>
<version>3.0.0</version>
<inherited>true</inherited>
<executions>
<execution>
<id>make-index</id>
<goals>
<goal>jandex</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
When i force the execution of the jandex goal with mvn io.smallrye:jandex-maven-plugin:3.0.0:jandex it creates an META-INF/jandex.jdx file, but it does not produce one when i run mvn clean install. This is not a solution since i need to build the project, run the jandex plugin and install it into my local repositories separately. Also, notice that im using the "io.smallrye" version of the jandex plugin since the "org.jboss" version seems to not work at all.
I figured it out. The jandex plugin was set in the <pluginManagement> section of the POM configuration, which made it not run on mvn clean install. I had to move it to the plugins section so it gets executed. Thanks #Ladicek for making me look closer and keep trying!
I have a sample project with two jpms modules. It is a maven project with one parent and two child modules.
A parent pom:
...
<modules>
<module>foo.api</module>
<module>foo.impl</module>
</modules>
...
API module pom:
...
<groupId>com.foo</groupId>
<artifactId>foo.api</artifactId>
...
API module-info:
module com.foo.api {
requires org.slf4j;
exports com.foo.api;
}
These are my settings for maven-javadoc-plugin (in parent pom):
<reporting>
<excludeDefaults>true</excludeDefaults>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.3.0</version>
<reportSets>
<reportSet>
<reports>
<report>javadoc-no-fork</report>
<report>test-javadoc-no-fork</report>
</reports>
</reportSet>
</reportSets>
<configuration>
<doclint>none</doclint>
<dependencySourceIncludes>
<dependencySourceInclude>com.foo:${project.artifactId}</dependencySourceInclude>
</dependencySourceIncludes>
<doctitle>Title - ${project.version}</doctitle>
<includeDependencySources>false</includeDependencySources>
<windowtitle>Title</windowtitle>
<additionalJOptions>
<additionalJOption>--no-module-directories</additionalJOption>
</additionalJOptions>
</configuration>
</plugin>
</plugins>
</reporting>
And when I run mvn javadoc:javadoc I get:
Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:3.2.0:javadoc (default-cli) on project foo.api: An error has occurred in Javadoc report generation:
Exit code: 1 - error: module not found: com.foo.api
Could anyone say how to fix it?
I found the solution. In case of modules, javadoc requires a compiles module descriptor, so it is necessary to do mvn compile javadoc:javadoc instead of mvn javadoc:javadoc
I have a lot of maven projects, which are dependent on each other.
I already have a super pom for the actual projects and this works pretty well.
Now I want to create a super pom for all my integrationtests projects. I did it the same, but every time I run maven test it failed.
[ERROR] Failed to execute goal on project *: Could not resolve
dependencies for project ::jar:0.0.1-SNAPSHOT: The following
artifacts could not be resolved: ::jar:0.0.1-SNAPSHOT,
::jar:0.0.1-SNAPSHOT, ::jar:0.0.1-SNAPSHOT, ::jar:0.0.1-SNAPSHOT: Could not find artifact *:***:jar:0.0.1-SNAPSHOT -> [Help 1]
The problem is that maven looks for jar files but my project consists of war projects. Here is my pom file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>***</groupId>
<artifactId>***-parent_IntegrationTests</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>***_IntegrationTests</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<modules>
<module>../***</module>
<module>../***</module>
<module>../***</module>
<module>../***</module>
<module>../***</module>
<module>../***</module>
</modules>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
Is there a way to tell maven to use the war files instead of jars?
Edit: Sorry if it is not clear enough. I want a single maven project to run all my integrationtest projects. each one is a maven project. Therefor I want to use a pom with modules (all the integrationtest project) in it. But every integrationtest project contains dependencies to my other projects and the problem I want to fix is that maven does not find my compiled projects because it looks for jar files but my projects are war files.
You can reference WARs as dependencies by using <type>war</type> in the dependency.
Recently, I wrote a Spring-Boot project and I wanted that Maven will be able to create a jar file that I'll be able to run by the command "java -jar ".
This is the pom.xml I wrote:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>SpringBootGame</groupId>
<artifactId>SpringBootGame</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
</dependencies>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.3.RELEASE</version>
<configuration>
<mainClass>com.game.Main</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
In order to build the jar file, I had to run the command: "mvn clean package spring-boot:repackage".
My questions are:
Why must I add spring-boot-maven-plugin? I already have spring-boot-starter-web dependency that adds spring-boot as a dependency and maven-compiler-plugin that builds a jar file from the code?
Can you think about a way to configure pom.xml file that I'll be able to get the jar file using the "native" command "mvn clean package" and not the cumbersome "mvn clean package spring-boot:repackage"?
Thanks
Why must I add spring-boot-maven-plugin? I already have spring-boot-starter-web dependency that adds spring-boot as a dependency and maven-compiler-plugin that builds a jar file from the code?
Because the plugin is what adds Maven support for Spring Boot
Can you think about a way to configure pom.xml file that I'll be able to get the jar file using the "native" command "mvn clean package" and not the cumbersome "mvn clean package spring-boot:repackage"?
It looks like you are missing the <packaging>jar</packaging> element in between your <project> </project> element.
The reason you had to run that lengthy command, is because you did not include the <executions></executions> element when including the plugin. Please see section 71.1 of the following docs:
https://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-maven-plugin.html#build-tool-plugins-include-maven-plugin
71.2 elaborates on the <packaging> element.
In the configuration of the maven plugin you have already in place, you need to add the executable block like :
<configuration>
<executable>true</executable>
</configuration>
this will create in the target folder the runnable jar that can be run by using java -jar command.
I've got a Maven project (submodule of a parent project) which I need to create a "jar with dependencies" for. I added the maven-assembly-plugin to the pom.xml, but it didn't create the artifact. I've slowly stripped everything else out of the pom.xml, until all that's left is dependencies and this plugin, and it still won't create a jar with dependencies. Watching the output of mvn clean package it runs clean, compile, and jar but never runs the assembly plugin. I don't know why. Here's the pom.xml, can anyone spot the problem?
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>project</groupId>
<artifactId>project-name</artifactId>
<version>1.0</version>
<name>project-name</name>
<properties>
<build.time>${maven.build.timestamp}</build.time>
<spring.framework.version>4.3.1.RELEASE</spring.framework.version>
<spring.security.version>4.1.1.RELEASE</spring.security.version>
<spring.webflow.version>2.4.2.RELEASE</spring.webflow.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<sourceDirectory>${project.basedir}/src/java</sourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/resources</directory>
</resource>
</resources>
<outputDirectory>${project.basedir}/target/classes</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
[snip]
</dependencies>
</project>
Maven reference :
Assemble an application bundle or distribution from an assembly
descriptor. This goal is suitable either for binding to the lifecycle
or calling directly from the command line (provided all required files
are available before the build starts, or are produced by another goal
specified before this one on the command line).
The asssembly:single goal may be used in two ways :
either by binding it to the lifecycle
or by calling it directly from the command line
You do no one of them.
You can for example do it to bind the plugin execution to the package phase :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<phase>package</phase> <!-- bind to the packaging phase -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
Now the mvn package or mvn install command will create the jar with dependencies.
You can also keep your actual plugin configuration and run the mvn assembly:single command.
The second way allows to create the jar with dependencies on demand and not for every build.
Which may be desirable if the jar creation is a long task that doesn't need to be executed at each build.