To make my life easier, I configured my maven to put my deployed application in a different folder (/deploy) than the default (so it doesn't mix with classes/, surefire-reports directories and so forth). It works fine, except that when I try to run mvn clean, it only deletes the jar and copied dependencies, but NOT the copied resources.
UPDATE It appears they are being deleted, but then get placed back immediately. It appears to be related to using Eclipse and Build Automatically, but I'm not sure why changing Maven's configuration would have this effect on Eclipse. END UPDATE
UPDATE 2 At the present moment, none of the answers are correct. This problem clearly has little to do with the deploy directory; it seems that maven-resources-plugin makes Eclipse copy resources as part of Build Automatically. But I'm not sure how to turn this off without stopping using maven-resources-plugin, and without stopping using Build Automatically I will give the bounty to someone who can explain how to do this. END UPDATE 2
Anyway, my directory looks something like this:
my-app
|-- pom.xml
|-- src
| |-- main
| | |-- java
| | `-- resources
| | |-- script.sh
| | `-- config
| | `-- app.properties
| `-- test
| |-- java
| `-- resources
`-- deploy
|-- my-app.jar <----- This gets deleted correctly
|-- lib <----- This gets deleted correctly
| |-- dependency1.jar <----- This gets deleted correctly
| |-- dependency2.jar <----- This gets deleted correctly
|-- config <----- This DOES NOT get deleted correctly
| `-- app.properties <----- This DOES NOT get deleted correctly
`-- script.sh <----- This DOES NOT get deleted correctly
Here's my pom snippet:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>${maven.jar.version}</version>
<configuration>
<archive>
<manifest>
<mainClass>my.main.Class</mainClass>
<packageName>my.main</packageName>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<excludes>
<exclude><!-- the files I don't want in my jar --></exclude>
</excludes>
<outputDirectory>${basedir}/deploy</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/deploy/lib</outputDirectory>
<includeScope>compile</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>install</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/deploy</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.5</version>
<configuration>
<filesets>
<fileset>
<directory>deploy</directory>
<includes>
<include>**/*</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
Stick to the Maven way and put your deploy directory under ${basedir}/target then your problem will fix itself. You can remove the custom plugin configuration for the clean plugin as well.
If question is how to disable eclipse to run specific plugin than you can put in under specific profile that is active by default
<project>
...
<profiles>
<profile>
<id>not-eclipse</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
...
</plugins>
</build>
</profile>
...
</project>
and place ! not-eclipse in profile settings of eclipse project
In your place I'd stick to the "Maven way". If you want a place where only your jar is stored do mvn install and refer to ~/.m2/repository/groupId/artifactId, if you want your jar packed with its configuration files and/or dependencies use the Maven Assembly plugin.
Note that Eclipse's automated rebuilding takes place also with the default configuration. Personally I let Eclipse handle its workspace the way it wants and perform command line builds in a separate check-out or by meeans of Jenkins.
Your issue reproduces on a sample project with resources. Run As -> Maven Clean has the output as mentioned later which only covers the cleaning up.
Although the latest version does not offer this screen, I'm guessing the goal process-resources still runs which would copy the resources to your output directory on running any Maven task.
I wonder why, when the Sonatype book mentions it, the plugin still doesn't show those options.
In a previous project of mine we used to remove the process-resources from Goals to run when updating project configuration to avoid resource processing as major tasks were handled from commandline.
Hope this helps.
P.S: I don't think your issue has anything to do with you changing the deploy directory.
Apache Maven 3.0.4 (r1232337; 2012-01-17 14:14:56+0530)
Maven home: C:\projects\workspace\abc\EMBEDDED
Java version: 1.7.0_04, vendor: Oracle Corporation
Java home: C:\Java\jre7
Default locale: en_US, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
[INFO] Error stacktraces are turned on.
[DEBUG] Reading global settings from EMBEDDED\conf\settings.xml
[DEBUG] Reading user settings from C:\Users\stackoverflow\.m2\settings.xml
[DEBUG] Using local repository at C:\Users\stackoverflow\.m2\repository
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10 for C:\Users\stackoverflow\.m2\repository
[INFO] Scanning for projects...
[DEBUG] Extension realms for project abc:abc:jar:0.0.1-SNAPSHOT: (none)
[DEBUG] Looking up lifecyle mappings for packaging jar from ClassRealm[plexus.core, parent: null]
[DEBUG] === REACTOR BUILD PLAN ================================================
[DEBUG] Project: abc:abc:jar:0.0.1-SNAPSHOT
[DEBUG] Tasks: [clean]
[DEBUG] Style: Regular
[DEBUG] =======================================================================
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Test 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] === PROJECT BUILD PLAN ================================================
[DEBUG] Project: abc:abc:0.0.1-SNAPSHOT
[DEBUG] Dependencies (collect): []
[DEBUG] Dependencies (resolve): []
[DEBUG] Repositories (dependencies): [central (http://repo.maven.apache.org/maven2, releases)]
[DEBUG] Repositories (plugins) : [central (http://repo.maven.apache.org/maven2, releases)]
[DEBUG] -----------------------------------------------------------------------
[DEBUG] Goal: org.apache.maven.plugins:maven-clean-plugin:2.4.1:clean (default-clean)
[DEBUG] Style: Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
<directory default-value="${project.build.directory}"/>
<excludeDefaultDirectories default-value="false">${clean.excludeDefaultDirectories}</excludeDefaultDirectories>
<failOnError default-value="true">${maven.clean.failOnError}</failOnError>
<followSymLinks default-value="false">${clean.followSymLinks}</followSymLinks>
<outputDirectory default-value="${project.build.outputDirectory}"/>
<reportDirectory default-value="${project.reporting.outputDirectory}"/>
<skip default-value="false">${clean.skip}</skip>
<testOutputDirectory default-value="${project.build.testOutputDirectory}"/>
<verbose>${clean.verbose}</verbose>
</configuration>
[DEBUG] =======================================================================
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) # abc ---
[DEBUG] Created new class realm maven.api
[DEBUG] Importing foreign packages into class realm maven.api
[DEBUG] Imported: org.apache.maven.wagon.events < plexus.core
...
Lots of such lines
...
[DEBUG] Imported: org.codehaus.plexus.* < plexus.core
[DEBUG] Imported: org.codehaus.plexus.personality < plexus.core
[DEBUG] Populating class realm maven.api
[DEBUG] org.apache.maven.plugins:maven-clean-plugin:jar:2.4.1:
[DEBUG] org.apache.maven:maven-plugin-api:jar:2.0.6:compile
[DEBUG] org.codehaus.plexus:plexus-utils:jar:2.0.5:compile
[DEBUG] Created new class realm plugin>org.apache.maven.plugins:maven-clean-plugin:2.4.1
[DEBUG] Importing foreign packages into class realm plugin>org.apache.maven.plugins:maven-clean-plugin:2.4.1
[DEBUG] Imported: < maven.api
[DEBUG] Populating class realm plugin>org.apache.maven.plugins:maven-clean-plugin:2.4.1
[DEBUG] Included: org.apache.maven.plugins:maven-clean-plugin:jar:2.4.1
[DEBUG] Included: org.codehaus.plexus:plexus-utils:jar:2.0.5
[DEBUG] Excluded: org.apache.maven:maven-plugin-api:jar:2.0.6
[DEBUG] Configuring mojo org.apache.maven.plugins:maven-clean-plugin:2.4.1:clean from plugin realm ClassRealm[plugin>org.apache.maven.plugins:maven-clean-plugin:2.4.1, parent: sun.misc.Launcher$AppClassLoader#769fe666]
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-clean-plugin:2.4.1:clean' with basic configurator -->
[DEBUG] (f) directory = C:\projects\rollbase2.0workspace\abc\target
[DEBUG] (f) excludeDefaultDirectories = false
[DEBUG] (f) failOnError = true
[DEBUG] (f) followSymLinks = false
[DEBUG] (f) outputDirectory = C:\projects\rollbase2.0workspace\abc\target\classes
[DEBUG] (f) reportDirectory = C:\projects\rollbase2.0workspace\abc\target\site
[DEBUG] (f) skip = false
[DEBUG] (f) testOutputDirectory = C:\projects\rollbase2.0workspace\abc\target\test-classes
[DEBUG] -- end configuration --
[DEBUG] Skipping non-existing directory C:\projects\rollbase2.0workspace\abc\target
[DEBUG] Skipping non-existing directory C:\projects\rollbase2.0workspace\abc\target\classes
[DEBUG] Skipping non-existing directory C:\projects\rollbase2.0workspace\abc\target\test-classes
[DEBUG] Skipping non-existing directory C:\projects\rollbase2.0workspace\abc\target\site
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.693s
[INFO] Finished at: Sun Sep 01 16:38:36 IST 2013
[INFO] Final Memory: 4M/121M
[INFO] ------------------------------------------------------------------------
It works fine, except that when I try to run mvn clean, it only deletes the jar and copied dependencies, but NOT the copied resources.
I realize that this is an older question, but it is the first question I found when investigating the same issue experienced by the OP. This is provided as a definitive answer for anyone else engaged in similar literary research as to why this behavior is observed.
It appears they are being deleted, but then get placed back immediately
When run from the command line mvn clean removes all build artifacts by deleting the target directory. However, when run from within Eclipse, it appears that target is not deleted. Furthermore, if non-default resources are defined such as those presented in the question, it appears that they are not deleted.
This is just an illusion and is the result of two distinct tasks. The first, mvn clean deletes the entire target directory. The second task is as a result of Project → Build Automatically causing M2E Builder execution of compile and test-compile phases during full and/or incremental workspace builds.
A prerequisite of these phases is the execution of several other phases such as generate-resources and process-resources (see Lifecycle Reference). These in turn, will cause the execution of resource goals such as those defined by the OP.
The end result of automatic builds is that the target directory is recreated containing:
OP's custom resources.
test-classes containing compiled code from src/test/java and resources from src/test/resources
test-classes containing compiled code and resources from src/test/java and src/test/resources, respectively.
Eclipse does not show classes and test-classes folders since they are marked as output folders (see Properties → Java Build Path → Source). However, since the OP's custom resources are not output directories, they are displayed, resulting in the illusion that mvn clean does not remove them.
If there is doubt, one can verify this by disabling the Java output folders option under Customize View... → Filters in the Project Explorer view. It should be noted that this filtering option is not available in the Package Explorer view. A simpler verification is to run mvn clean and examine the contents of the project directory via the operating system's console or file explorer.
Lastly, running mvn clean from the command line, will verify that it does delete the target directory as expected; only to reappear once Eclipse's automatic build kick in after changes in the IDE. In general, it is a good idea to build projects from the command line once in a while to ensure that the build configuration is IDE agnostic.
Add the following fileset to the maven-clean-plugin section
<fileset>
<directory>${basedir}/deploy/config</directory>
</fileset>
It looks like Maven Builder is getting invoked from Eclipse, which is inturn populating files again. I guess you can try disabling Maven builder and Maven nature for your project in eclipse to see if it solves problem.
To disable Eclipse Maven builder this go to
Eclipse Project Properties -> Builders -> Maven builder
Disabling eclipse maven nature
All I am saying is problem is due to eclipse-maven integration and not maven
Related
I'm using maven-dependency-plugin:copy-dependencies to copy all dependencies into target/dependency directory. My pom.xml is:
<plugin>
<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>
</execution>
</executions>
</plugin>
version of plugin is latest: 3.1.2 (defined in parent pom).
This definition is working fine with one exception: it copies all test dependencies into target directory, where I need only runtime dependencies required for running target jar.
I tried to exclude it usgin <excludeScope> configuration like described in the documentation:
<configuration>
<excludeScope>test</excludeScope>
</configuration>
But it makes the build failing with message:
[INFO] --- maven-dependency-plugin:2.10:copy-dependencies (copy-dependencies) # app ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.006 s
[INFO] Finished at: 2021-02-15T10:32:26+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-dependency-plugin:2.10:copy-dependencies (copy-dependencies) on project app: Can't exclude Test scope, this will exclude everything. -> [Help 1]
I don't really understand why excluding the test scope will exclude everything, since without excluding test scope, the target directory contains all runtime dependencies too (along with test deps).
What could be the problem with excluding test dependencies? How to do it correctly?
PS: Please don't suggest me using assembly or other fat-jar plugins here, since I'm copying dependency jars intentionally for Docker image build optimization: one layer for dependencies, another for jar, where dependencies layer is always cached until any dependency changed:
COPY target/dependency /usr/lib/app/lib
COPY target/${JAR_FILE} /usr/lib/app/target.jar
The solution is probably in the includeScope description:
Scope to include. An Empty string indicates all scopes (default). The scopes being interpreted are the scopes as Maven sees them, not as specified in the pom. In summary:
runtime scope gives runtime and compile dependencies,
compile scope gives compile, provided, and system dependencies,
test (default) scope gives all dependencies,
provided scope just gives provided dependencies,
system scope just gives system dependencies.
This means I would try with <includeScope>runtime</includeScope>.
To exclude dependencies which are under test scope is to use includeScope runtime instead of the excludeScope as the plugin documentation for test means 'everything'
EDIT: This question should absolutely not be closed. I'm NOT asking how to create an executable jar. A jar doesn't need to be executable to be run from the terminal. For example, if I have have this code:
package com.dogzilla.maven.quickstart;
public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World" );
}
}
...and Maven builds it, it creates quickstart-0.0.1-SNAPSHOT.jar. Which is not, ahem, 'executable'.
I can run it from the terminal quite successfully with this:
java -cp /opt/workspace/eclipse/java/quickstart/target/quickstart-0.0.1-SNAPSHOT.jar com.dogzilla.maven.quickstart.App
The problem, as I have written below, is experienced when using an external dependency. </end edit>
I have a simple Maven project in Eclipse (2020-6). It was set up by doing the following in Eclipse:
1. File -> New -> Other... Maven -> Maven Project
2. Used the maven-archetype-quickstart archetype
Group ID: com.dogzilla.maven
Artifact ID: quickstart
Right click the pom file -> select Add Dependency -> enter:
Group ID: com.google.code.gson
Artifact ID: gson
Version: 2.8.6
Which I verified on https://search.maven.org/
Here's the POM file:
<?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.dogzilla.maven</groupId>
<artifactId>quickstart</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>quickstart</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<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>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<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>
</plugins>
</pluginManagement>
</build>
</project>
Here's the source code:
package com.dogzilla.maven.quickstart;
import com.google.gson.Gson;
public class App
{
public static void main( String[] args )
{
Gson gson = new Gson();
System.out.println(gson.toJson("Hello World!") );
}
}
I then right-clicked on the POM file -> Run As -> Maven Build...
and here is the output:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/eclipse/java/plugins/org.eclipse.m2e.maven.runtime.slf4j.simple_1.16.0.20200610-1735/jars/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [file:/opt/eclipse/java/configuration/org.eclipse.osgi/5/0/.cp/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/opt/eclipse/java/plugins/org.eclipse.m2e.maven.runtime.slf4j.simple_1.16.0.20200610-1735/jars/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [file:/opt/eclipse/java/configuration/org.eclipse.osgi/5/0/.cp/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.SimpleLoggerFactory]
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< com.dogzilla.maven:quickstart >--------------------
[INFO] Building quickstart 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) # quickstart ---
[INFO] Deleting /opt/workspace/eclipse/java/quickstart/target
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) # quickstart ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /opt/workspace/eclipse/java/quickstart/src/main/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) # quickstart ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /opt/workspace/eclipse/java/quickstart/target/classes
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) # quickstart ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /opt/workspace/eclipse/java/quickstart/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) # quickstart ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to /opt/workspace/eclipse/java/quickstart/target/test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) # quickstart ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.dogzilla.maven.quickstart.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.022 s - in com.dogzilla.maven.quickstart.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) # quickstart ---
[INFO] Building jar: /opt/workspace/eclipse/java/quickstart/target/quickstart-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.967 s
[INFO] Finished at: 2020-12-13T20:00:27-07:00
[INFO] ------------------------------------------------------------------------
But if I run:
java -cp /opt/workspace/eclipse/java/quickstart/target/quickstart-0.0.1-SNAPSHOT.jar com.dogzilla.maven.quickstart.App
It fails with:
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gson
at com.dogzilla.maven.quickstart.App.main(App.java:13)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gson
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
... 1 more
The thing is if I change System.out.println(gson.toJson("Hello World!") ); to plain 'ol System.out.println("Hello World"); it works. So I know the porblem isn't with my java command or how I set the project up outside of the dependency getting resolved.
So the question is, I'm not sure how this is failing on the dependency. I was under the impression Maven managed all that for you. Why is this failing to run?
The jar file that created from your project only contains classes that written by you. If you need to run the application, you need to include all the necessary dependencies (either direct or transitive) in your classpath.
If you need a single jar file that you can execute without other dependencies, Please follow this to create a fatjar.
Use the Maven plugin mentioned in comment https://stackoverflow.com/a/65486325/679858 or use the Maven Shade plugin described here: https://maven.apache.org/plugins/maven-shade-plugin/
Your question was "Why does it run from Eclipse and not from console?":
If you run it from Eclipse then the Maven plugin in Eclipse knows the full runtime classpath and so it works. If you run it in console with the created JAR file then that JAR file only contains the classes of your sources but not the transitive dependencies, e.g. Google GSON. But if you use the Maven Assembly plugin or the Maven Shade plugin then you can create a JAR file which contains all the transitive dependencies of your project. That jar could be executed like you wrote it in your example.
try remove gson from .m2 folder then run maven install again.
You are not providing the path to the additional, transitive, dependencies of your project in the java command, which is why it fails.
You are using maven to build your project, not to execute your class: this is not Maven purpose, although it can do it using maven-exec-plugin. Eclipse is different: it uses Maven information (with m2e) and provides a context to run classes, context that includes dependencies.
The option -cp, explained in depth at Oracle Web Site: java (15), accepts one or more path to list of directories, jar and zip to search for class files:
--class-path classpath, -classpath classpath, or -cp classpath
A semicolon (;) separated list of directories, JAR archives, and ZIP archives to search for class files.
Specifying classpath overrides any setting of the CLASSPATH environment variable. If the class path option isn't used and
classpath isn't set, then the user class path consists of the current
directory (.).
As a special convenience, a class path element that contains a base name of an asterisk (*) is considered equivalent to specifying a
list of all the files in the directory with the extension .jar or .JAR
. A Java program can't tell the difference between the two
invocations. For example, if the directory mydir contains a.jar and
b.JAR, then the class path element mydir/* is expanded to A.jar:b.JAR,
except that the order of JAR files is unspecified. All .jar files in
the specified directory, even hidden ones, are included in the list. A
class path entry consisting of an asterisk (*) expands to a list of
all the jar files in the current directory. The CLASSPATH environment
variable, where defined, is similarly expanded. Any class path
wildcard expansion that occurs before the Java VM is started. Java
programs never see wildcards that aren't expanded except by querying
the environment, such as by calling System.getenv("CLASSPATH").
So you need to fix your command to provides gson and any other compile/runtime/provided dependencies you may add later:
CLASSPATH=''
CLASSPATH+=";$HOME/.m2/repository/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar"
CLASSPATH+=";/opt/workspace/eclipse/java/quickstart/target/quickstart-0.0.1-SNAPSHOT.jar"
CLASSPATH="${CLASSPATH:1}" # remove leading ';'
java -cp "${CLASSPATH}" com.dogzilla.maven.quickstart.App
The man says that you can use ; to separate entries; that is true at least for Windows. However on other Linux based OS (which seems to are on due to /opt being used), this can also be :: that what appassembler does when writing CLASSPATH.
Do note that you will have to adapt the path manually to retarget the actual location of gson.jar (I guessed from what maven does by default).
You can also use appassembler or launch4j to do the trick for you. You can also use build-classpath to build the classpath (it may also work from command line).
I have a maven build that is extremely slow. I would like to know whether there is a way to profile maven execution in order to find out which are the most time-consuming steps.
Later I will want to compare these times between builds for older versions (which were faster), so they should be ideally in a format that can be compared/diffed/graphed.
This is the quickest possible way:
export MAVEN_OPTS="-Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS \
-Dorg.slf4j.simpleLogger.showDateTime=true"
mvn test
Results in
MAVEN_OPTS="-Dorg.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss,SSS -Dorg.slf4j.simpleLogger.showDateTime=true" mvn test
17:06:07,330 [INFO] Scanning for projects...
17:06:07,447 [INFO]
17:06:07,447 [INFO] ------------------------------------------------------------------------
17:06:07,448 [INFO] Building bimble-server 0.0.1-SNAPSHOT
17:06:07,448 [INFO] ------------------------------------------------------------------------
17:06:07,747 [INFO]
17:06:07,748 [INFO] --- maven-resources-plugin:2.6:resources (default-resources) # bimble-server ---
If you then add that environment variable to your shell's config file (like ~/.bashrc or ~/.profile) you will have those timings every time you use Maven.
Based on info from Stanley Hillner's blog:
Out of the box solution is the takari maven profiler:
https://github.com/takari/maven-profiler
Sample output from its page:
org.apache.maven:maven-core:3.1.2-SNAPSHOT
clean 176ms
org.apache.maven.plugins:maven-clean-plugin:2.5 (default-clean) 176ms
initialize 408ms
org.codehaus.mojo:buildnumber-maven-plugin:1.2 (create-noncanonicalrev) 349ms
org.codehaus.mojo:buildnumber-maven-plugin:1.2 (create-buildnumber) 59ms
generate-sources 408ms
org.codehaus.modello:modello-maven-plugin:1.8.1 (standard) 369ms
org.codehaus.modello:modello-maven-plugin:1.8.1 (standard) 28ms
org.codehaus.modello:modello-maven-plugin:1.8.1 (standard) 11ms
generate-resources 933ms
org.apache.maven.plugins:maven-remote-resources-plugin:1.4 (default) 932ms
process-resources 225ms
org.apache.maven.plugins:maven-resources-plugin:2.6 (default-resources) 224ms
compile 4s 522ms
org.apache.maven.plugins:maven-compiler-plugin:2.5.1 (default-compile) 4s 522ms
process-classes 6s 880ms
org.codehaus.mojo:animal-sniffer-maven-plugin:1.6 (check-java-1.5-compat) 5s 814ms
org.codehaus.plexus:plexus-component-metadata:1.5.5 (default) 946ms
org.sonatype.plugins:sisu-maven-plugin:1.1 (default) 120ms
process-test-resources 173ms
org.apache.maven.plugins:maven-resources-plugin:2.6 (default-testResources) 173ms
test-compile 818ms
org.apache.maven.plugins:maven-compiler-plugin:2.5.1 (default-testCompile) 818ms
process-test-classes 134ms
org.codehaus.plexus:plexus-component-metadata:1.5.5 (default) 110ms
org.sonatype.plugins:sisu-maven-plugin:1.1 (default) 23ms
test 11s 306ms
org.apache.maven.plugins:maven-surefire-plugin:2.12 (default-test) 11s 306ms
package 1s 371ms
org.apache.maven.plugins:maven-jar-plugin:2.4 (default-jar) 502ms
org.apache.maven.plugins:maven-site-plugin:3.3 (attach-descriptor) 869ms
https://github.com/jcgay/maven-profiler is a similar handy tool. It's easy to setup and use. (Having something like it or EventSpy takari/maven-profiler in core Maven as an option would certainly be neat; comment in https://issues.apache.org/jira/browse/MNG-4639 ..)
This functionality has been included in Maven3. Here's the associated ticket: https://issues.apache.org/jira/browse/MNG-4639
If you need to do the same with Maven2 I'd recommend building yor own plugin that is hooks into all phases of execution ( or just the ones you need to track).
i just create a gist here : https://gist.github.com/boly38/7316378
This is a sample example on how to log datetime of some maven lifecycle steps.
Of course you could adapt this sample to set your own output format (and graph it ...).
Hope this help
Extract :
<profile>
<id>stats</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>log_validate</id>
<phase>validate</phase>
<goals><goal>run</goal></goals>
<configuration>
<tasks>
<tstamp><format property="stepTstamp" pattern="dd-HH:mm:ss" locale="en,US" /></tstamp>
<echo file="stats.log" append="true"
message="${line.separator}${line.separator}${stepTstamp} validate${line.separator}"/>
</tasks>
</configuration>
</execution>
(...)
<execution>
<id>log_process_sources</id>
<phase>process-sources</phase>
<goals><goal>run</goal></goals>
<configuration>
<tasks>
<tstamp><format property="stepTstamp" pattern="dd-HH:mm:ss" locale="en,US" /></tstamp>
<echo file="stats.log" append="true"
message="${stepTstamp} process-sources${line.separator}"/>
</tasks>
</configuration>
</execution>
(...)
In my project I have a configuration such as
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<commandlineArgs>${additionalExecArgs} -jar ${project.build.directory}/someDir/some.jar</commandlineArgs>
<executable>java</executable>
<classpathScope>runtime</classpathScope>
</configuration>
</execution>
</executions>
</plugin>
to start an executable JAR using Maven exec:exec.
The additionalExecArgs property is empty by default.
In NetBeans I can run this goal by specifying the following action in the nbactions.xml file:
<action>
<actionName>run</actionName>
<goals>
<goal>exec:exec</goal>
</goals>
</action>
To debug this goal in NetBeans I've added the following action to the nbactions.xml file:
<action>
<actionName>debug</actionName>
<goals>
<goal>exec:exec</goal>
</goals>
<properties>
<jpda.listen>true</jpda.listen>
</properties>
<activatedProfiles>
<activatedProfile>debug</activatedProfile>
</activatedProfiles>
</action>
So in addition to running exec:exec it sets the NetBeans (?) property jpda.listen to true and activates the Maven profile debug.
I've also added the following Maven profile to my POM:
<profile>
<id>debug</id>
<properties>
<additionalExecArgs>-Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address}</additionalExecArgs>
</properties>
</profile>
With this configuration I can simply run the debug action from the project context menu/ toolbar.
Please note the jpda.address Maven property however. This property seems to get populated by NetBeans somehow.
If I try to run exec:exec with the debug profile in IntelliJ or Eclipse I'm getting an error, likely because the jpda.address Maven property doesn't get set.
E.g. I'm getting the following error in IntelliJ:
/usr/lib/jvm/java-8-oracle/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:42300,suspend=y,server=n -Dmaven.home=/usr/share/maven -Dclassworlds.conf=/usr/share/maven/bin/m2.conf -Dfile.encoding=UTF-8 -classpath /usr/share/maven/boot/plexus-classworlds-2.x.jar:/opt/idea-IC-141.1010.3/lib/idea_rt.jar org.codehaus.classworlds.Launcher -Didea.version=14.1.3 -Dmaven.repo.local=/home/someUser/.m2/repository exec:exec -P debug
Connected to the target VM, address: '127.0.0.1:42300', transport: 'socket'
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building test-application 0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.4.0:exec (default-cli) # test-application ---
ERROR: transport error 202: connect failed: Verbindungsaufbau abgelehnt
ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
JDWP exit error AGENT_ERROR_TRANSPORT_INIT(197): No transports initialized [debugInit.c:750]
FATAL ERROR in native method: JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_INIT(197)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
The port changes with every call.
I've tried and replaced jpda.address with a fixed address/ port such as 127.0.0.1:8000, but I'm getting the same error and now in NetBeans, too.
So how can I get a similar behavior in IntelliJ and Eclipse as in NetBeans and debug an exec:exec goal using a Maven run configuration directly without having to resort to a remote debugger configuration or such?
It sounds like you can set up a Remote debug configuration in intellij with a Before launch Maven Goal.
Set it up as follows:
Run/Debug Configurations -> Add Remote -> Add Before Launch -> Maven -> specify correct module and goal.
I have a large JEE Maven Multi module project, and share a custom set of rules and suppressions for Checkstyle via build-tools module. I find very hard to release a stable version of this build-tools due to the testing of this same module.
Each time I run a Maven phase, I get a different execution result.
This is Checkstyle configuration in parent pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${checkstyle.plugin.version}</version>
<configuration>
<skip>${skipQATests}</skip>
<configLocation>qa/checkstyle_rules.xml</configLocation>
<propertiesLocation>${checkstyleDir}/checkstyle.properties</propertiesLocation>
<suppressionsLocation>qa/suppressions.xml</suppressionsLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
<failOnViolation>true</failOnViolation>
<linkXRef>false</linkXRef>
</configuration>
<executions>
<execution>
<id>checkstyle-compile</id>
<phase>compile</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I'm trying to find a pattern in the executions, project is set to fail in one particular check and I cannot find the 'bug'.
I execute compile maven phase (mvn clean compile) and it fails on the given check.
I execute package maven phase (mvn clean package) and it fails too.
I execute again compile phase (mvn clean compile) and it doesn't fail (all SUCCESS)
I execute again package and it fails
It does not fail for a couple of runs and then it fails again on some different execution
I know this behavior is kind of difficult to trace without all project information. But is there any kind of procedure, log, tool that would give more information on debuging this problem so that I can determine if it's a bug or some mis-configuration??
Thanks in advance!!
UPDATE:
I have just executed the same mvn command twice on the sub-module I'm testing Checkstyle (test that forces a rule violation) - mvn checkstyle:check -X
Result was different from each other, the main differences are that the CORRECT EXECUTION (the one that fails the build does not find the files at the first try) and the WRONG EXECUTION (the one that ends in SUCCESS finds the configuration files at the first attempt)
EXEC_1: ...
[DEBUG] The resource 'qa/suppressions.xml' was not found with resourceLoader org.codehaus.plexus.resource.loader.FileResourceLoader.
[DEBUG] The resource 'qa/suppressions.xml' was found as jar:file:/C:/Users/usuario/.m2/repository/com/company/tools/build-tools/0.0.2-SNAPSHOT/build-tools-0.0.2-SNAPSHOT.jar!/qa/suppressions.xml.
[DEBUG] Adding the outputDirectory file:/C:/LAB/PRJ/prj-ejbws/target/classes/ to the Checkstyle class path
[DEBUG] The resource 'qa/checkstyle_N4_JEE.xml' was not found with resourceLoader org.codehaus.plexus.resource.loader.FileResourceLoader.
[DEBUG] The resource 'qa/checkstyle_N4_JEE.xml' was found as jar:file:/C:/Users/usuario/.m2/repository/com/company/tools/build-tools/0.0.2-SNAPSHOT/build-tools-0.0.2-SNAPSHOT.jar!/qa/checkstyle_JEE.xml.
[DEBUG] The resource 'ubic.properties' was found as C:\LAB\PRJ\ubic.properties.
[INFO] Starting audit...
[INFO] --------------------------------------------
[INFO] BUILD FAILURE
[INFO] --------------------------------------------
[INFO] Total time: 1.542s
[INFO] Finished at: Thu Feb 20 16:35:22 CET 2014
[INFO] Final Memory: 8M/20M
[INFO] --------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-checkstyle-plugin:2.11:check (default-cli) on project GestionDelContacto-opsa-ejbws: Failed during checkstyle execution: There are 2 checkstyle errors.
EXEC_2:...
[DEBUG] The resource 'qa/suppressions.xml' was found as jar:file:/C:/Users/usuario/.m2/repository/com/company/tools/build-tools/0.0.2-SNAPSHOT/build-tools-0.0.2-SNAPSHOT.jar!/qa/suppressions.xml.
[DEBUG] Adding the outputDirectory file:/C:/LAB/PRJ/prj-ejbws/target/classes/ to the Checkstyle class path
[DEBUG] The resource 'qa/checkstyle_N4_JEE.xml' was found as jar:file:/C:/Users/usuario/.m2/repository/com/company/tools/build-tools/0.0.2-SNAPSHOT/build-tools-0.0.2-SNAPSHOT.jar!/qa/checkstyle_JEE.xml.
[DEBUG] The resource 'ubic.properties' was not found with resourceLoader org.codehaus.plexus.resource.loader.ThreadContextClasspathResourceLoader.
[DEBUG] The resource 'ubic.properties' was not found with resourceLoader org.codehaus.plexus.resource.loader.JarResourceLoader.
[DEBUG] The resource 'ubic.properties' was found as C:\LAB\PRJ\ubic.properties.
[INFO] Starting audit...
[INFO] --------------------------------------------
[INFO] BUILD SUCCESS
[INFO] --------------------------------------------
[INFO] Total time: 1.570s
[INFO] Finished at: Thu Feb 20 16:37:05 CET 2014
[INFO] Final Memory: 8M/20M
[INFO] ---------------------------------------------
any clue?
Stop using Maven, run CheckStyle separately. You already have sufficient "clues": sometimes Maven initializes CheckStyle correctly, sometimes not, and depending on unreliable infrastructure is a bad idea.