Make a jar that has a classifier by default - maven

We have a project called core-services. This builds three jars:
core-services-client Contains all client classes
core-services-server: Contains all server and client classes
core-services-test: Contains all junit classes
Right now, I build the core-services-server jar by default, and then use assemblies to build the client and test jars. If a developer wants to use the client or test jars, they must specify a classifier. However, when they want to depend upon the server jar, they don't specify a classifier.
This will lead to developers just using the server jar when they really should be using the client jar. I'd like to build all three jars to require a classifier when using them as a dependency. However, I can't do this when specifying the project:
<groupId>com.vegicorp</groupId>
<artifactId>core-services</artifactId>
<version>1.0.0</version>
<classifier>server</classifier>
<packaging>jar</packaging>
I know I can use <finalName> to call the default jar core-services-server, but I want to make sure that if a developer depends upon the core-services, they must say whether they want the server, the client, or the testing classes. If I merely rename it, they will get the server jar by default.
How can I specify that the default jar has a classifier of server?

I figured it out. I can put the default classifier into the maven-jar-plugin configuration in my pom.xml:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<!-- All other configuration information is in the parent pom -->
<configuration>
<classifier>server</classifier>
</configuration>
</plugin>
When I do mvn deploy, I get a warning that No primary artifact to deploy, deploying attached artifacts instead, and all three jars deploy with classifiers.

Related

Maven EAR project for multiple application servers

I have a EAR project that I want automatize the building process using maven exclusively.
The EAR project has
Standard jar modules
Web modules
EJB modules
RAR modules
To be able to execute the product in Jboss 4.2.3 and WebSphere 7 the EJB and RAR descriptors must be configured in different way. Also we have one jar library for each app server.
What I want is to be able to build one EAR for each apps server using the same projects, and for that I need
Include a JAR module depending of the app server
Use the customized descriptor in the EJB/RAR modules depending of
the app server
Package all this customized modules in an EAR
Can this be done using the same set of project in maven?
Sure. Have a look at profiles in maven. They allow you to adjust various things (from the link) like:
<repositories>
<pluginRepositories>
<dependencies>
<plugins>
<properties> (not actually available in the main POM, but used behind the scenes)
<modules>
<reporting>
<dependencyManagement>
<distributionManagement>
a subset of the element, which consists of:
<defaultGoal>
<resources>
<testResources>
<finalName>
The best is to create separate modules like ear-websphere, or ear-jboss and make an appropriate pom file which contains the needed configuration for maven-ear-plugin.

How to auto-deploy EJB jar with TomEE maven plugin

I have a stateless EJB SOAP Web Service that is packaged in jar file.
Is it possible to setup auto-deploy with Tomee maven plugin when the app consists of only one EJB jar file?
For example, this site indicates that a web context defined in server.xml is required. My synch setup is same as the site suggests.
mvn compile
command does nothing but compile the sources as it normally does.
Is there a possibility to setup something like this with EJB jar or is a WAR package needed in any case?
Thanks.
UPDATE
In order to get the TomEE Maven plugin to work at all with jar files, I added the following in pom.xml configuration section
<apps>
<app>my.group:my-ejb-app:1.0:jar</app>
</apps>
We use the maven tomcat7 plugin to do exactly this. Here's the trick, because Apache TomEE is JEE6, you can deploy EJBs in wars.
So there are two ways to do what you want... One, skip the Jar packaging for your application and make your EJBs be WARs. If this doesn't sound appealing, the other way is to create a separate project that's a WAR, but pulls in your EJB jar as a dependency.
In either case, then you can then use the tomcat7 plugin to deploy your projects easily to Apache TomEE like this mvn tomcat7:deploy provided you fill out the server section of your pom correctly. Example:
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<server>crabs</server>
<url>http://crabs/manager/text</url>
<path>/${project.artifactId}</path>
<update>true</update>
</configuration>
</plugin>
</plugins>
</build>
Make sure you have a user in tomcat-users.xml on the server that has the proper deployment permissions to manager-text. Also, put the server configuration into your ~/.m2/settings.xml:
...
<servers>
<server>
<id>crabs</id>
<username>deploy</username>
<password>your password</password>
</server>
...

Add test jars in maven-jetty-plugin or create test-war with maven-war-plugin

I'm using maven to build a multi-module webapp. I would like to run my integration tests in their own module and use the jetty plugin. In order to get everything to work I will need to add a couple of jars to the classpath for the war but I see no option for such a thing in the documentation http://www.eclipse.org/jetty/documentation/current/jetty-maven-plugin.html#deploy-war-running-pre-assembled-war
I am able to deploy the war but it fails because it's missing the two jars I need to add.
Is there a way for me to add a couple extra jars to the plugin configuration?
If not, is there a way for me to package a "test-war" like you can do with test-jar in maven?
There are multiple ways to extend the web application classpath with the jetty-maven-plugin. The most appropriated for you would be to set the extraClasspath field in the webAppConfig block of your plugin configuration:
<configuration>
...
<webAppConfig>
...
<extraClasspath>path/to/your/custom-dependency.jar</extraClasspath>
</webAppConfig>
</configuration>
The documentation is not very consistent about that. But the javadoc is quite clear.
You can find relevant configuration examples on my jetty plugin wiki page.
Add the dependencies directly to the plugin's <dependencies/>. No need for scopes or anything -- they'll not enter your final artifact, but rather -- only be used by the Jetty plugin during execution.

How can the production jar specify its own dependencies when added to other project as a dependency?

If the question title can't make it clear, take me explain here in more detail. Suppose the production jar of one of my Maven applications needs to be used into my other Maven web-application. Adding that jar to my second application Maven dependency doesn't add its transitive dependencies. Also, the jar in itself is an application.
One way is to look at the POM of the first application and add those in the POM of the other application. But then, how do central Maven jars add their own transitive dependencies when added to some project.
In other words, if I add commons-io.jar Maven dependency to my project, it automatically adds its transitive dependencies. But when I add myjar.jar as a Maven dependency (scope->system) then it doesn't automatically adds its transitive dependencies.
I think that I should develop my first application as some other archetype which can be used in such a case. Please advise me how to proceed further.
Sorry for this newbie question. Actually, I'm new to Maven and I've started using Netbeans-embedded-maven to create applications. I really like the way Maven simplifies the job.
edited
Seems like I should explain in more detail. So here is it.
Suppose I wrote a program/application that used A.jar,B.jar,C.jar and my production output was X.jar (which obviously doesn't contain other jars within as per maven default build). The above A,B,C jars are present in maven central repository and were added as dependency to my project. The project build jar is X.jar
Now I write another application in which I added X.jar as a system dependency, now what I want is that A.jar, B.jar, C.jar added automatically to the project since they are transitive dependencies for X.jar
Hope so I've explained it clear this time. Please forgive me for my writing style in case you didn't understand earlier.
One solution is to build X.jar containing all dependencies within it using something like this
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.nitinsurana.mlmmaven.Start</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
But I'm looking for something that automatically adds transitive dependencies of a system dependency.
The system scope is not supposed to be used for actual jar dependencies that will be packaged with another application. Quoting from the official documentation:
Dependencies with the scope system are always available and are not looked up in repository. They are usually used to tell Maven about dependencies which are provided by the JDK or the VM. Thus, system dependencies are especially useful for resolving dependencies on artifacts which are now provided by the JDK, but where available as separate downloads earlier. Typical example are the JDBC standard extensions or the Java Authentication and Authorization Service (JAAS).
You should use the default compile scope.
As others have suggested, use the (default) compile scope and add <exclusions> for transitive dependencies you don't want / need.
See: Maven > Optional Dependencies and Dependency Exclusions
I had gone through the link provided by #Sean and it seems like what I want is not possible.
Shall I vote to delete this question ?
Although the answer is IT CAN'T BE DONE and heres' why :
Project-A -> Project-B
The diagram above says that Project-A depends on Project-B. When A declares B as an optional dependency in its POM, this relationship remains unchanged. Its just like a normal build where Project-B will be added in its classpath.
Project-X -> Project-A
But when another project(Project-X) declares Project-A as a dependency in its POM, the optional dependency takes effect. You'll notice that Project-B is not included in the classpath of Project-X; you will need to declare it directly in your POM in order for B to be included in X's classpath.
Taken from Official Documentation
So, your X module is mavenized? Then you can install it locally with mvn clean install and then use it in another projects with all transitive dependencies and compile scope. This case is good till you do everything on you own machine. As far as you want to share the code with others or configure CI build you need X with its pom available to others. The best way to do this is to have your own artifactory, accessible from all other machines. You install X there and use it with compile scope as ususal, just need to add new repo to pom.

How to distribute a binary dependency in maven?

I'm trying to convert a project from ant to maven.
The unit tests depend on a third party binary jar, which is not available in any public maven repositories.
How do I make maven handle this situation? I have found two solutions, neither of which are acceptable. First is to use a system dependency; this doesn't work because a) the dependency should only be for the tests, and b) the dependency is not found by eclipse after generating an eclipse project.
Second is to manually install the dependency in a local repository. This seems to be the recommended way. I don't want to do this because I want users to be able to build and test with a simple 'mvn test'. If users have to read a document and copy/paste some shell commands to be able to build and test, then something's wrong.
I suppose it would be OK if maven itself installed the dependency in the local repository as part of the build - is this possible, and if so, how?
Aled.
You may want to look at install:install-file. You can make it execute in the early phase of your project (validate or initialize) via standard means.
On the second thought, if it fails because of missing dependency in the same project, there are couple more options. One is to call ant script via antrun plugin to install artifact.
Or create additional module not dependent on your artifact to be executed prior to main module and have that module install artifact as described earlier.
First of all my way would be using a repository manager such as nexus and installing this dependency to there.
However there is another solution. You can include this 3rd party jar to your project and with test plugin you can configure to include it in classpath such this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>path/to/additional/resources</additionalClasspathElement>
<additionalClasspathElement>path/to/additional/jar</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
By the way, I hope that you are aware of that maven is executing surefire plugin in order to run tests by default lifecycle.

Resources