Maven: use dependencies from repository when running command line app? - maven-2

I've used Maven to build my command line application. Now I'm going to distribute it as a jar file, and I need to handle the app's dependencies.
I don't want to include all dependencies in the jar file as described here.
The environment where my app will be run has Maven. I'd like Maven to run my jar looking at file META-INF/groupId/artifactId/pom.xml inside the package so it knows what the dependencies are and can find them in the repository.
Any ideas ?

Include a main class in the jar that 1) extracts the pom to a temporary file, and 2) launches a new maven process using this file with the -f parameter and the goals dependency:resolve and dependency:build-classpath
like this:
mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DoutputFile=/temp/classpath.txt
then 3) reads the newly created classpath file and 4) launches a new java process using the new classpath file
java -cp yourjar.jar;<created classpath>
Your pom.xml will have to include all required repository information, of course

We can use, maven-jar-plugin instead, why because the classpath generated is not getting accommodated while copy paste with java command in command-line.
mvn -f /temp/tempfile.xml dependency:resolve dependency:build-classpath -DmdepoutputFile=/temp/classpath.txt
So wasn't able to succeed copying classpath.txt for the command,
java -cp yourjar.jar;<created classpath>
Mine is spring-boot application hence I have the following line with BOOT-INF/lib. For you it can be WEB-INF/lib in case of .war file or just lib/ in case of ant build based projects.
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
BOOT-INF, comes up by spring-boot:repackage maven command and with the use of plugin,-spring-boot-maven-plugin that I have not Included here.
Please find maven-jar-plugin config here.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.pakage.SampleApplication</mainClass>
<!--<classpathPrefix>lib/</classpathPrefix>-->
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>BOOT-INF/lib/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>
<!--<customClasspathLayout>BOOT-INF/lib/$${artifact.groupIdPath}/$${artifact.artifactId}-$${artifact.version}$${dashClassifier?}.$${artifact.extension}</customClasspathLayout>-->
</manifest>
</archive>
</configuration>
</plugin>

Related

Visibility of plain jar in tycho-surefire-plugin

The problem
I am faced with the following scenario:
The sources of an Eclipse test plugin (tycho packaging type eclipse-test-plugin) depend on a "plain" jar (read: non-OSGi jar). I managed to get the tests to compile and run in Eclipse, however when running Maven/Tycho from the command line, tycho-surefire-plugin fails to execute the tests because the jar is not visible at test time. This results in a java.lang.NoClassDefFoundError while attempting to load a class from the jar.
Looking at mvn -e -X output does not reveal anything significant.
My question is, how can I include the jar in the classpath of tycho-surefire-plugin when running Maven/Tycho from the command line?
Attempts
Here is everything I have tried so far:
Use <extraRequirements> as per the tycho-surefire-plugin documentation. This however fails because the jar's packaging type is jar, while <extraRequirements> expects one of the eclipse-xxx packaging types.
For a good measure I also tried
<configuration>
<dependencies>
<dependency>
<groupId>. . .</groupId>
<artifactId>. . .</artifactId>
<version>. . .</version>
<scope>system</scope>
<systemPath>path-to-the-jar</systemPath>
</dependency>
</dependencies>
</configuration>
but the packaging type is still considered to be jar.
Use <argLine> as per tycho-surefire-plugin documentation:
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-surefire-plugin</artifactId>
<configuration>
<argLine>-cp path-to-the-jar</argLine>
</configuration>
however this appears to have no effect as the java.lang.NoClassDefFoundError persists.
Include the jar in the Eclipse test plugin. The jar is present in the MANIFEST.MF
Bundle-ClassPath: the.jar
in the build.properties
bin.includes = META-INF/,\
the.jar
and in the .classpath (although this doesn't matter for tycho-surefire-plugin).
<classpathentry exported="true" kind="lib" path="the.jar"/>
tycho-surefire-plugin once again reports java.lang.NoClassDefFoundError.
Create a dedicated Eclipse plugin to house the jar. This is for the most part equivalent to 3, where the Eclipse test plugin simply depends on this new dedicated Eclipse plugin. The java.lang.NoClassDefFoundError still rears its head.
Transition to Tycho 2.x.x since it supports the Directory location type. Unfortunately it is not possible to include the jar in the target definition because its packaging type is jar.

Building ANTLR4 source to get source jar

I could download the newest ANTLR4 (antlr-4.5.3-complete.jar) from the download page (http://www.antlr.org/download.html).
Putting the jar file in the lib directory of IntelliJ project to make the jar as a dependency to see everything works fine.
I'm trying to look into the ANTLR's source code by tracing with debugger, but I can't as I don't have the source jar.
I found the source code, and an instruction to build ANTLR (
How to build ANTLR itself). However, the instruction uses bild.py that is not included in the source.
I found the bild.py from Sam Hawell's tunnelvisionlabs/antlr4, but when I copy the script and run it, I got errors:
target all
require compile
require parsers
build compile
skipping mkjar_complete
Traceback (most recent call last):
File "/Users/smcho/Downloads/antlr4-4.5.3/bilder.py", line 847, in processargs
target()
File "bild.py", line 182, in all
mkjar()
File "bild.py", line 133, in mkjar
mkjar_complete()
File "bild.py", line 80, in mkjar_complete
require(compile)
File "/Users/smcho/Downloads/antlr4-4.5.3/bilder.py", line 434, in require
raise Exception()
Exception
bild failed
What might be wrong? How to build ANTLR4 to get source jar file?
If you want to get source (and/or javadoc), you should simply use ivy. You could also use maven as you wrote, but ivy is simpler IMHO. http://mvnrepository.com/artifact/org.antlr/antlr4/4.5.3
maven is the tool to build the jar files as is described in this document: https://github.com/antlr/antlr4/blob/master/doc/building-antlr.md
mvn compile gets the compilation done.
For getting the source jar file, pom.xml should be updated.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Then mvn package will make the source jar in tool/target directory.
For the runtime jar, the target directory is runtime/Java/target.
mvn install will install the jars into local repository.
References
Generate source code jar for Maven based project

Maven update jar before packaging in WAR

I have a project where I am packaging a WAR using simple maven-war-plugin. Along with all other dependencies one of the dependency say 'abc.jar' which is getting packaged in war contains a default spring configurations which I would like to update with the custom one before packaging. I have maven profile configured to be activated if following build command applied;
mvn clean install -DframeworkPacakging=XYZ
I am trying to use 'truezip-maven-plugin' to overwrite my custom spring configurations inside in 'abc.jar' present in 'target/aretfacts-id/WEB-INF/lib' but when maven-war-plugin finishes I loose my changes because war plugin takes the file from dependency definition. How can I solve this issue and what are my options?
P.S. Distributing configuration is not desirable as this setup would be used for Embedded Jetty Server running within Eclipse
to prevent inclusion of the original jar file, I would use go for approach suggested on: https://www.mail-archive.com/users#maven.apache.org/msg38537.html
Use <scope>provided</scope> for this dependency to keep it out of the
lib directory.
to include the repackaged one, I'd follow suggestion from: How to make Maven copy resource file into WEB-INF/lib directory?
Try changing the configuration of the maven war plugin to include a webResource:
<configuration>
<webResources>
<resource>
<directory>pathtorepackagedjar</directory>
<includes>
<include>**/abc.jar</include>
<includes>
<targetPath>WEB-INF/lib</targetPath>
</resource>
</webResources>
</configuration>

maven surefire additionalClasspathElements single test

I have one main and one test config file which is shared by several maven projects. While testing, I am specifying the classpath to the directory where the test config file is.
This works fine if the whole project is tested/build but it doesn't work while running single tests. The config file is not found in the classpath.
here is the config:
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<element>${project.parent.basedir}/conf/test</element>
</additionalClasspathElements>
</configuration>
</plugin>
any ideas why surefire ignores the property for running single tests?
thank you
Shouldn't it be:
<additionalClasspathElements>
<additionalClasspathElement>${project.parent.basedir}/conf/test</additionalClasspathElement>
</additionalClasspathElements>
put the config file in src/test/resources folder and try it .It should automatically be picked up. OR try to put under src/main/resources and use tag to point to that config file in the pom.xml of the project .Make use of 2.5 version of maven-surefire plugin.

create manifest without classpath entries in ejb-client jar, but have classpath entries in main ejb jar using maven-ejb-plugin

I am using maven-ejb-plugin to generate the ejb jar and the client jar. Also I am using archive to generate the manifest file.
But the problem is I need the classpath entries in the ejb jar but not in the client jar.
Is there any configuration available to addClasspath only in the main jar and in the client jar do not set the class path?
Thanks in advance.
I don't think that's supported. If this is an option, exclude the manifest file from the client jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<clientExcludes>
<clientexclude>META-INF/MANIFEST.MF</clientexclude>
</clientExcludes>
...
</configuration>
</plugin>
If not, I'm afraid you'll have to do some post processing (to unpack, modify the manifest, repackage the archive) with the antrun plugin.