Is there way to get parent directory for ${basedir} in my pom.xml? Currently I have
<earSourceDirectory>${basedir}/EAR/src/main/resources</earSourceDirectory>
but I need to access parent directory of basedir as my resources lies in different maven project.
How can I get the parent folder of ${basedir}?
In the children:
<properties>
<main.basedir>${project.parent.basedir}</main.basedir>
</properties>
In the grandchildren:
<properties>
<main.basedir>${project.parent.parent.basedir}</main.basedir>
</properties>
${project.basedir}/../
However, access resources in a different module is something I try to avoid. I'd suggest using the unpack goal of the maven-dependency-plugin.
Please, don't try to go outside the basedir, because it's considered a very bad practice.
Even if you succeed now, it will be the start of a workaround over workaround, trying to battle Maven. In the end, Maven will win.
If a developer checks out a directory with a pom.xml, it should be able run the project with mvn verify without any references to other directories.
If these are shared resources, make it a separate project and include it as a dependency (search for multi module projects). Or use the maven-remote-resources-plugin to pull these resources into your project.
I had the requirement of moving zip generated in MainDirectory/Submodule/target/ to MainDirectory/target/.
I tried all solutions from everywhere but I was unable to solve. I finally tried Ant plugin in pom.xml of submodule to copy as below:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>copy to parent target</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<copy todir="../target/" overwrite="true" flatten="true">
<fileset dir="${basedir}/target/"/>
</copy>
</target>
</configuration>
</execution>
</executions>
</plugin>
Related
I have a project called BigProject.
The structure is:
BigProject
-firstModule
--pom.xml
-secondModule
--pom.xml
-thirdModule
--pom.xml
-pom.xml
I want to create a unique jar called BigProject.jar
At the moment, if I do a clean install, I have returned a jar for each module.
Can you explain me how to do?
thanks
Well you'd need a custom class loader for that. Thankfully folks have already contributed some plugins to ease up your life. You can have a look over Ant's create jar task or spring-boot's repackage goal, whatever stays convenient for you. Example below:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.1.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Each module-info.java which lives in the default package will be compiled to module-info.class.
Therefore, one JAR cannot contain multiple modules.
I am trying out a Simple Java Web Start project based on the Oracle Tutorial. I am using maven to package it as a webapp and deploy it to application server. The full source code is available here
https://github.com/KiranMohan/dynamic-tree-javaws-sample-project
The maven project structure is like
parent
|--lib
|--webapp
The webapp module is a maven war module. It is required to package lib.jar at the root of webapp.war. NOT under WEB-INF/lib.
How to achieve this in maven?
I found that the right way to do this is to use the maven-dependency-plugin.
Since "lib.jar" is not used in the compile phase of "webapp" module, it is only a package time dependency. Using maven-dependency-plugin, I can copy lib.jar to any required directory during the prepare-package phase. The maven-war package would then include the lib.jar in the .war package.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>prepare-package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>[ group id ]</groupId>
<artifactId>[artifact id]</artifactId>
<version>[ version ]</version>
<outputDirectory>${project.build.directory}/${project.artifactId}</outputDirectory>
</artifactItem>
</artifactItems>
<!-- other configurations here -->
</configuration>
</execution>
</executions>
</plugin>
Update:
There is a webstart-maven-plugin that does a better job of packaging javaws applications. See my sample project
https://github.com/KiranMohan/dynamic-tree-javaws-sample-project
for details
Well how i said in the comments for sake of readability here is a part of the answer:
Since Maven will always store the dependencies of a web project under its WEB-INF/lib folder by default i (i am no Maven expert ...) would try to place my lib.jar inside the /target folder of the project before the phase package is executed.
NOTE: I havent tried it out so you will have to adjust the paths - expecially the output path so your lib.jar is placed properly to be packed into the root of the war (e.g. if you open your war there will be a lib.jar next to folders such as WEB-INF).
<!--
lets assume the root of my project would be under C:/devjba/projectX this equals the maven
variable ${project.basedir}.
from there the output-directory would be located under C:/devjba/projectX/target which equals the
maven variable ${project.build.directory}. This is the location a .war would be placed in after
the build
lets assume the required jar lib.jar is located under C:/devjba/projectX/misc which would equal to
the expression: ${project.basedir}/misc
-->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>foo</id>
<!-- may adjust to another phase before package but make sure your plugin is bound to a phase
because otherwise it wont be invoked during build! Now its bound to the first phase of the
default lifecycle for packaging type war -->
<phase>process-resources</phase>
<goals>
<!-- use the copy-resources goal of this plugin - it will copy resources :) -->
<goal>copy-resources</goal>
</goals>
<configuration>
<!-- this points to /target of the current project, you may adjust it to wherever it must be placed to be packed into the root of the war (just try&error) -->
<outputDirectory>${project.build.directory}</outputDirectory>
<resources>
<resource>
<!-- this points to a folder /misc under the project root where we expect the lib.jar -->
<directory>${project.basedir}/misc</directory>
<!-- unless you specify what to include anything of the above directory will be included -->
<includes>
<include>lib.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
As i said i have no experience in signing JARs at all but there is a plugin called maven-jarsigner-plugin which i guess will do the job (i would sign it, then move it, then package the war) with a manual - i recomend you try to configure it according to my "example configuration of the maven-resource-plugin and post a new question directly containing your two plugin configurations. Dont forget to link to this question in that case. And also leave this question open so someone with a better approach may correct my way).
I am using properties-maven-plugin to read a external property file under root dir to maintain the version of parent module since there are quite a number of sub-modules in my project and the dependency tree is kinda deep.
It works fine when I build locally and install the artifacts into local repo but got the 401 error when I try to use "mvn clean deploy" to publish them to Nexus. I am pretty sure this is caused by the ineligible artifact name(releaseurl/{external.version}), external.version is supposed to be the property read from the external file. However, it ended up not being read and it just worked fine when I explicitly declare the version in the project.parent.version tag. Any thoughts or workaround? or even how you handle the version control when trying to use same version for parent and child in all the modules when dealing with a multi-module porject.
The maven pom for the plugin is as below, I saw some comments online regarding the phase, not sure if it will work if change initialize to something else:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>external-file.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
I have started playing with Maven2 and I'm attempting to port one of my projects from ant to maven. I have managed to build ear file, use jaxb and other bits, but there is one thing left I don't know how to approach.
I have WAR module, with ExtJS code, and I'm using JSBuilder to create and package the code nicely. This is done as ant task and looks like this:
<target name="-pre-compile" description="Building Frontend Libraries">
<java jar="web/lib/dev/JSBuilder2.jar" failonerror="true" fork="true" >
<arg line="--projectFile web/lib/dev/frontend.jsb2 --homeDir web/lib"/>
</java>
</target>
I am wondering what would be the 'maven' way to do this? Is there a way I can do it purely in maven (had a look at maven:exec plugin but is a bit confusing) or do I have to call ant from maven to achieve this?
Thanks
The exec-maven-plugin is the correct answer (though you want the java goal). You need to bind it to a lifecycle phase. Look at the usage page for an example. In your case, you'd need something like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>jsbuilder</id>
<goals>
<goal>java</goal>
</goals>
<phase>compile</phase>
<configuration>
<mainClass><!-- fill in from jar's META-INF/MANIFEST.MF --></mainClass>
<argument>--projectFile</argument>
<argument>web/lib/dev/frontend.jsb2</argument>
<argument>--homedir</argument>
<argument>web/lib</argument>
</configuration>
</execution>
</executions>
<configuration>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>true</includePluginDependencies>
</configuration>
<dependencies>
<!-- a bit nasty, would be better if jsbuilder2 available in a maven repo. -->
<dependency>
<groupId>com.extjs</groupId>
<artifactId>jsbuilder2</artifactId>
<version>2.0.0</version>
<scope>system</scope>
<systemPath>web/lib/dev/JSBuilder2.jar</systemPath>
</dependency>
</dependencies>
</plugin>
If you're a big user of JSBuilder2, it'd be worth asking Cencha if they can release it to the maven central repo. Point them at OSS Repository Hosting.
I'm just starting to use Maven, (evaluating it, really) and I need to be able to quickly generate a JAR file for my application and a directory with all the dependencies (for example, lib) so that I can deploy those two to be run in a stand-alone manner. Generating the JAR file with the proper manifest is easy, but I do not know how to get Maven to copy the dependencies for the current project into a lib directory that I can deploy.
Since this is for a stand-alone Java applications, I am not interested in deploying to a Maven repository, that is also fairly trivial, or at least easily googleable.
I've found out how to do everything except copy the dependent JAR files into some specified directory. This is the workflow I'm looking for:
$ mvn clean
$ mvn package
$ cp -r target/{lib,myApp.jar} installLocation
Then, running myApp.jar from installLocation as a JAR file should "just work" regardless of my $CLASSPATH.
To try and pre-empt some answers:
I do have a Main-class: set, and it works fine.
I've also set the classpath in the MANIFEST.MF, and that works fine too.
I've found out how to use <classpathPrefix> and <classpathMavenRepositoryLayout> to make this work -- but only on my machine. (via: <classpathPrefix>${settings.localRepository}</classpathPrefix>)
What you want to investigate is Maven's dependency plugin. Add something similar to the following to pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<outputDirectory>
${project.build.directory}
</outputDirectory>
</configuration>
</plugin>
Then run mvn clean dependency:copy-dependencies to copy perform the copy. Combine this with the assembly plugin and you can package everything into a self contained archive for distribution.
I did not care for the Shade plugin since it rolls all the packages from all the jars together.
To include all of the external libs you can use the Dependency Plugin as mentioned above.
This example will create a "lib" directory under "target/classes" before the "package" phase.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/classes/lib</outputDirectory>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeGroupIds>
junit,org.hamcrest,org.mockito,org.powermock,${project.groupId}
</excludeGroupIds>
</configuration>
</execution>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>sources</goal>
</goals>
</execution>
</executions>
<configuration>
<verbose>true</verbose>
<detail>true</detail>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
Take a look at maven's dependency plugin, specifically the copy-dependencies goal. The usage section describes how to do exactly what you want.
To do it from the command line just do:
$ mvn dependency:copy-dependencies -DoutputDirectory=OUTPUT_DIR
Yet another one is appassembler plugin
What I like about it is that it packages the app in a form ready to use (with a .bat file ans such)
It sure can. You need to use the shade plugin which can be done by adding
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.3-SNAPSHOT</version>
<configuration>
<!-- put your configurations here -->
</configuration>
</plugin>
to your project.
Using maven.repo.local one can collect all jars, but, they are collected into a directory with maven hierarchy (.m2).
mvn install -Dmaven.repo.local=./pick/some/folder
You can then collect them (on Linux):
mkdir flat-repo
find ./pick/some/folder -type f -name "*.jar" | xargs -I'{}' cp '{}' flat-repo/