Maven project with prebuilt jar - maven

Currently I am not using Maven in any way whatsoever, but since I am writing a library I would like other developers to be able to use it as a Maven dependency. It seems like the easiest way to do this would be to have a Maven project which just contains the jar.
However, all the examples I've seen of pom.xml have build logic in them and I was wondering how I am supposed specify the prebuilt jar as the resulting artifact.
Thanks!

I do not know if I understand you correctly, so maybe I am commenting something totally different.
If you want to offer your project as Maven dependency for other projects, the project must be somewhere to be downloaded (Maven central repository, your company Nexus...) and your project must have something to identify it: groupId, artifactId and the version. You can specify these separately when installing the artifact, or you can provide a pom that contains this metadata, along with dependencies if there are any. Both approaches are explained here.
Then adding something like this in the project that wants your project as dependency, it should work.
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
Still, since you control this project, you might want to consider converting your library to a Maven project to reap other benefits of Maven (in some IDEs like Eclipse there is an option that convert a regular Java Project in a Maven project), and in the generated pom.xml is the info which is mention above.
Here an example of a basic pom.xml to be a jar.
<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.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Maven Quick Start Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Extracted from here --> http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html

Related

including test-jar in the runtime scope

i got a war-project and in the test-jar of it, we have aside of the jUnit testcases also the mocks to the neighbor systems (for instance, the roles and users management system).
and we have a maven profile called mocking that adds the test-jar dependency to the war-project, at runtime, so that the mocks are available for the developer, but do not end up by error in production.
<profile>
<id>mocking</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>runtime</scope>
</dependency>
...
not very clean, i know, but we did not want to have just another artifact for only a hand full of mock clases, and it worked so far well with Maven 3.3.9.
now we need a feature of Maven 3.5.0, so i updated to the latest Maven 3.6.2 and get following error:
The project com.my-project:web:0.0.1-SNAPSHOT has 1 error:
'dependencies.dependency.[com.my-project:web:0.0.1-SNAPSHOT]' for com.my-project:web:0.0.1-SNAPSHOT is referencing itself.
which is kind of borderline case.
imho, and since the dependency is of scope runtime, it should be allowed.
is this a bug?
can anyone figure out a better way to achieve this?
many thanks
Michael
UPDATE 20191125:
Without full pom files or at least an example which looks very like your original projects it's hard to guess....
Here a small pom-file to reproduce the problem:
<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>my.project</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
with that file, and nothing else, mvn compile works fine with v3.3.9 but breaks with v3.6.2
If you use the normal setup for creating a test-jar this implies the test-jar is created as supplemental artifact to your usual artifacts which needed to be distinguished from each other which has to be achieved by using the <classifier>tests</classifier>.

Maven: pin dependency version where dependency is managed by a BOM

We use a Maven BOM to manage dependencies of a suite of libraries. The dependencyManagement section of the BOM generally uses version ranges to specify versions of these libraries, e.g., [2.0,2.1) Child pom.xml's using the BOM do not specify versions for these managed dependencies. (Edit for clarification: we use specific versions for third party dependencies, the ranges are used for internal libraries that are undergoing development, where the versions can change rapidly. We define version ranges to ensure broad compatibility between these libraries, i.e. all within the same major version.)
(Note that this is not a multi-module project. Libraries and service projects using the BOM mechanism just declare it as a parent and pull it from a Nexus repository. they are not built together.)
We also have some build system scripts that use versions:resolve-ranges to pin the versions of dependencies appearing in our library and service pom.xml's (not the BOM's pom.xml). These pom.xml's with resolved ranges are checked in to source control and tagged, so that if we need to roll back a deployment to an earlier version, we can use that tagged pom.xml to make a build that uses the same dependency versions as the original build, even if a newer version of a dependency is now available (and thus resolve-ranges would come up with the newer version if we reran it).
I just noticed that these two mechanisms are not working well together. Running versions:resolve-ranges on the library or service pom.xml only resolves the ranges in that pom.xml. Versions under dependency management are still not specified, so if we made a new build using this pom.xml, we'd get the latest dependency version in range at build time. Not what we want!
Is there a way to use versions:resolve-ranges (or any other plugin or technique) to resolve the managed versions and stick them into the child pom.xml?
Here is a contrived example.
The BOM:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.maventest</groupId>
<artifactId>myproject</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<name>myproject</name>
<url>http://maven.apache.org</url>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>[2.0, 2.3]</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Child project using the BOM (one managed dependency, one unmanaged):
<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/maven-v4_0_0.xsd">
<parent>
<groupId>com.maventest</groupId>
<artifactId>myproject</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../myproject/pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.maventest</groupId>
<artifactId>mytest</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>mytest</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>[3.8, 3.9)</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Snippet from mvn dependency:tree showing effective versions of dependencies:
[INFO] com.maventest:mytest:jar:1.0-SNAPSHOT
[INFO] +- commons-lang:commons-lang:jar:2.3:compile
[INFO] \- junit:junit:jar:3.8.2-brew:test
Dependency section from mytest pom.xml after mvn versions:resolve-ranges:
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.2-brew</version>
<scope>test</scope>
</dependency>
</dependencies>
So the unmanaged dependency is resolved, as expected. But the managed one is not. How can I get it to be resolved too?
Forgot about this question! In the end I could never find a way to pin the managed versions which were based on ranges. So I did stop defining the versions in the BOM and just specified them with ranges in each child pom. More boilerplate in the child poms, but not that bad.
We were still able to define properties that specified the ranges in the BOM which the children could use, making it a bit easier to bump all the ranges all when necessary.

Maven: How to import dependency of type pom?

I am trying to migrate a java application to maven. There are some dependencies which have been provided as jar files so far. One of these dependencies is jung2, which is available from the maven repository: mvnrepository.com
I need all of the provided modules and I do not understand how to declare this dependecy correctly in my pom.xml such that all corresponding jar files are downloaded and the classes are available at compile time.
This is what my pom.xml file looks like right now:
<?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>groupId</groupId>
<artifactId>myProject</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/net.sf.jung/jung2 -->
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung2</artifactId>
<version>2.0.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
I also tried leaving out <scope>import</scope> and put the dependency into the dependencies section. When executing mvn compile or mvn package, error message occur that the corresponding packages do not exist.
If I additionally add a dependency inside dependencies but outside of dependencyManagement, e.g.
<dependencies>
<dependency>
<groupId>net.sf.jung</groupId>
<artifactId>jung2</artifactId>
</dependency>
I receive an error about missing version. But as far as I understood, this should not be necessary due to dependencyManagement? If I also add <version>2.0.1</version>, then I get the following error message:
Failure to find net.sf.jung:jung2:jar:2.0.1
The dependencyManagement tag is used generally when you have a multi module project in maven (where you will have parent-child relationship).
If you specify any dependencies within the dependencyManagement tag, it would NOT actually download the dependencies.
Putting the dependency within this tag simply means that this dependency is available (to download / to use) for the child pom. The child pom will have to explicitly provide the groupId and the artifactId co-ordinates to download and use the jar to compile its classes.
If you just have a single module project (looks like yours is a single module project) then you can fix this issue by not using the dependencyManagement tag.
Simply put your jars in the dependencies tag.
For ex:
<dependencies>
<dependency>
<groupId>com.abc</groupId>
<artifactId>def</artifactId>
<version>1.0.0</version>
<type>pom</type> // This will now download the pom and its associated transitive dependent jars
</dependency>
<dependency>
<groupId>com.pqr</groupId>
<artifactId>xyz</artifactId>
<version>1.0.0</version>
<type>pom</type> // This will now download the pom and its associated transitive dependent jars
</dependency>
</dependencies>
Like I said before, the dependencyManagement tag will mostly make sense to use if you have a multi-module project, which isn't your case.

Maven modify dependency jar manifest files

I'm sorry in advance I can't give the exact code as I don't have it at hand right now. However, I ran into a problem while trying to package my project into a jar. I used maven assembly plugin in my pom.xml to assemble all dependencies and project jar into one place. But now I need all of those dependency jars to have a custom manifest file. Is it possible to inject some properties with Maven itself somehow? Now the only solution I came up with is to use Maven's shade plugin and create an uber-jar, but the problem is that some of dependencies have custom manifests (like Spring framework ones) which gets lost and only one manifest is generated for the uber-jar. Is it possible to somehow tell maven to unpack dependencies, edit manifestEntries and pack them up again and assemble together with the project jar in a zip?
Long story short: basically what I want to find out, is would it be possibly to somehow modify a file inside one of the dependencies jar or in all dependency jars at once? Let's say my project has a dependency of spring-beans. Now I would like to modify a specific file inside spring-beans.jar, specifically manifest.md before I assemble them in one zip which should contain project.jar and spring-beans.jar (with a modified manifest.md). I think something similar is achievable with maven antrunner plugin?
Example:
<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.mycompany.app</groupId>
<artifactId>project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Project</name>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/src.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>
I want to modify manifest.md in spring-core.jar, spring-context.jar and spring-beans.jar. I know I can use shade plugin to make an uber jar which would have one manifest.md which I could edit within shade's configuration, but if it is possible to somehow modify specific dependency jars alone I think it would be more fool proof and I could use these libraries among several applets.

Maven and dependencies

I have a simply POM like this :
<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.sim</groupId>
<artifactId>log4j</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>com.sim</groupId>
<artifactId>sim-java</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../sim-java/pom.xml</relativePath>
</parent>
<name>log4j</name>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>compile</scope>
</dependency>
</dependencies>
I run mvn clean package on this project and a JAR is created as expected.
When I navigate into this JAR, I thought that I would see a JAR named log4j-1.2.17.jar inside it but it's not the case.
Using dependency with compile scope does not include JAR into packaging version of project ?
Thank you for clarification
The jar:jar plugin of maven just compiles your source and bundles it into a jar. Just like building a jar out of ant or bare hands, no dependency jars will be bundled in the jar. Jars cannot have dependent jars bundled inside them and even if they did, they cannot be loaded by the default class loader.
If you are looking to build a ejb-jar, then you might want to consider a EJB plugin
Check this link for various plugins that you can exploit.

Resources