How to avoid creating empty jar in non-Java Maven project? - maven

I have a Maven project which uses a jdeb plugin to generate a deb (Ubuntu installer) package with some simple shell scripts that I would like to send to a customer to be able to deploy easily. This project has no Java whatsoever. I am not specifying in the pom.xml that it should package a jar. However, an empty jar does get packaged in the project's target directory anyway.
How can I avoid creating this empty jar file? I am not sure if it gets included in the deb package but if it does, it is just dead weight size-wise.

Got it figured. In the pom.xml the following needs to be added at the same hierarchy level where the <name>...</name> is for that project:
<packaging>pom</packaging>
Otherwise
<packaging>jar</packaging>
is assumed as a default.

Related

Maven on the empty project downloads tons of dependencies

I use Maven on daily basis in my work for more then 5 years. But I never tried to test the minimum dependencies project.
So I created a new directory on my disk and put inside a pom.xml file. It is the most simple pom file you can create. It contains only this:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>info.jikra</groupId>
<artifactId>whatever</artifactId>
<version>0.1</version>
</project>
And that's it. There is nothing more. No other directories, not a single Java file, nothing.
Then I cleared my local repository and ran mvn clean install in the folder with my pom file.
Maven downloaded tons of dependencies I don't need. My project is empty, there is only one pom file. Yet, there are more then 7,6M of files in my local repository, now.
I'm not any kind of Maven master, so I wonder why all those dependencies are necessary. Does anyone know?
Your project has some predefined plugins declared as well as packaging (default is jar) which defines a list of additional plugins as well as their bindings. Those are getting downloaded along with their transitive dependencies.
You can run mvn help:effective-pom in order to see what's actually present in your project.
You could also see plugins and their dependencies with: mvn dependency:resolve-plugins

include jar of one module to another

I have maven projet with this architecture:
++parent-project
+module-a
+module-b
module-b is a web application. it will be run on Jboss AS 7.1.1. I'm using netbeans IDE.
Now module-b depend on module-a. this is a porm section of module-b:
<dependency>
<groupId>groupid</groupId>
<artifactId>module-a</artifactId>
<scope>compile</scope>
</dependency>
When i build the war file of module-b, module-a is not present to lib folder ( in war file. i open it with archive explorer ). therefore JBoss return ClassNotFoundException.
I'm tried differends scope ( compile , provided , runtime , test ). But nothing.
Please how can i solve this.
First of all, I think you should try to see how does it work in "pure" maven, without the IDE at all (NetBeans). So my answer will be based only on maven knowledge:
A couple of facts:
Module b has to have the following in pom: <packaging>war</packaging> This will instruct maven that you really want to get a war from this module.
When packaging WAR is specified in some pom, maven will take all the dependencies defined in this pom and will put them into the WEB-INF/lib folder of the war. Automatically. Of course, you can customize the output, but its more advanced stuff (see Maven WAR plugin if required)
All the dependencies have to be defined with group id, artifact id, and version at least. So make sure that you have the dependency on module a with version. There is no need to fiddle with scopes in this case. The default scope (if you don't specify a scope at all) is 'compile' which is fine.
Go to the directory of module b and from within the directory type: mvn dependency:tree. Once its done, please carefully observe the output, especially make sure that module a is listed (with a correct version) in a tree.
Sometime to make sure that no stale artifacts reside in the local m2 repository you might want to delete all the jars of your project from there and then execute the mvn package command again. The war has to be created in module b/target - and this is the WAR you should check out.
Note, all these steps are done without any interaction with NetBeans at all.

Maven build order

I have a multi-module maven build and I need one particular module (lets call it project-A) to be build at the end. It depends on a module (lets call it project-B) that holds native code that gets compiled to a dll and installed into the maven repository as a zip file using some maven trickery. As it doesn't depends on it directly because the native code is not a java jar, I use Maven Dependency Plugin to unpack the zip file and place the native dll in my build directory. Everything is working fine except for the building order. It builds first project-A in spite of being declared the other way around in the tag in the parent. I would like to tell maven that project-A depends on project-B. I tried to add project-B as a dependency, but as it builds no jar it throws an ERROR, also this seemed hacky to me. Any help would be appreciated.
Just declare dependency in project A to project B and it will work fine. It does not matter if the project B is a native rather than a java project. Just make sure you declare the dependency correctly taking the packaging into account as type.. (which is probably pom so you would have
<dependency>
<groupId>...</groupId>
<artifactId>B</artifactId>
<version>...</version>
<type>pom</type>
</dependency>
in Project A)
The order in which you specify the modules in the parent Pom is also relevant. Maven actually builds in this order unless it has to build a module out of sequence due to direct dependencies.

Maven Assembly plugin. Any way to unzip/untar an archive straight from the descriptor file, rather than relying on antrun plugin?

I'm using maven assembly plugin version 2.2.1 to build a package in a custom, proprietary format.
As a part of this process, I need to extract a bunch of external archives (by external I mean they are not listed as maven dependencies, but they are arbitrary files on the filesystem).
Do you know if maven assembly is able to do that ? I've looked and apparently, it is able to extract a bunch of dependencies in an arbitrary folder, but it is unable to extract an external archive.
Using the <unpack>true</unpack> in your <dependencySet> is the way to go.
External archives are not supported by Maven. So you will need to attach them using, e.g. build-helper:attach-artifact then you can reference it via the <dependencySet>
Update
One of the comments wanted to know how you could avoid installing the attached artifact into the maven repository (local/remote)
The solution to that is to use a dummy module that is a non-transitive dependency.
We are relying on the assembly being built not being used as a transitive dependency.
So you start with a dummy module, which will look a little something like
<project>
...
<packaging>pom</packaging>
...
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.install.skip>true</maven.install.skip>
<!-- or you could override the plugin configuration for a safer - but less quick - solution -->
</properties>
...
</project>
That dummy module can attach the files using build-helper:attach-artifacts
The your assembly module will just list the dependencies with <scope>provided</scope> and <optional>true</optional> as a guard against becoming transitive dependencies. (not necessary if the assembly is say the installer bundle and will not be consumed by other Maven builds.
And there you go, the compressed content will be streamed from one archive to the other and the raw file will not be copied to the remote repo... but you will always need to build the hack module in any reactor that builds the assembly.
"arbitrary files on the filesystem" does not mean much, from maven point of view.
You should be able to run your maven pom from any point "your machine", "the integration server (jenkins...)". Ant is a tool for "home made" build, maven promotes convention over configuration, and reusability.
Therefore, any resources your project depend on should be either a dependency, or somehow included in your project .
I expect all my projects to be buildable as id, with a simple svn check out. Anything that is not in the project should be downloaded from mvn repositories.
So When I have to write an assembly project, I make sure everything is available in the project, as resources. If not, you can always build a simple project/pom for shared resources, or use some special plugins that do that for you.

Copying a jar from package to a resource folder of a web project using Maven

I have 2 java projects which are Maven projects.
One is a desktop app which has a plugin (maven-assembly-plugin) that I am using to 'package' all the dependencies that this application requires into one large jar. When this project is packaged (i.e. mvn clean package), it creates two jar files in the target folder. One of the jar file (childApp-0.0.1-SNAPSHOT.jar) is a smaller which doesnt have the dependencies embeded and the other jar file (childApp-0.0.1-SNAPSHOT-jar-with-dependencies.jar) is a larger file that has all the dependencies in it.
My other project is a web-based project and it creates a war file after it is packaged. I require the (childApp-0.0.1-SNAPSHOT-jar-with-dependencies.jar) file to copied to the resource folder of the web based project. More specifically, the jar file needs to be copied to the {webApp}\WEB-INF\classes folder.
How can I achieve this using Maven?
I have tried putting these two projects under a parent multi module project where I have the childApp packaged first and having a the webApp have a dependency on this childApp. This kind of works except it is copying the (childApp-0.0.1-SNAPSHOT.jar) file into the {webApp}\WEB-INF\lib folder. I can handle the file location being different from what I ideally wanted but I cant seem to get Maven to include the other large (childApp-0.0.1-SNAPSHOT-jar-with-dependencies.jar) file into {webApp}\WEB-INF\lib folder.
Any thoughts would be much appreciated.
ps: my web-app project is essentially a JNLP project.
You could try adding an additional dependency for the larger jar like the following:
<dependencies>
<dependency>
<groupId>some.group</groupId>
<artifactId>childApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>jar-with-dependencies</type>
</dependency>
...
</dependencies>

Resources