Instruct Maven to use Ivy's generated classpath - maven

We are adding new code to an existing project that uses a custom build system developed with Ant and Ivy for dependency management.
Our new team is used to Maven and its features like testing execution, cobertura reports, etc.
Our question is: is it viable to add a pom.xml matching the current project structure, but instruct Maven to load its classpath from the "lib" dir already filled by Ivy?
In other words: we want to use Maven without its dependency management.
One really dirty approach would be to generate one big jar from the libdir and config the pom.xml to include just that... but we believe there should be cleaner approach.
Any idea or recommendation?
Note: we are not interested in generating a pom.xml with dependencies from the Ivy config, we just want Maven to rely on Ivy's generated classpath. No need to discriminate between test/runtime/compile classpath.

This is our final setup to solve this:
For each Ivy legacy project, use ivy:makepom and manual inspection to figure out the dependencies that we need to send to the new projects (Maven-based). This is a one-time process for each project.
Modify the legacy build system in a way that, every time a project is built, the identified dependencies are also exported to a mvn repo. Because de build machine holds the internal repo, we just use mvn install.
In the new maven projects, declare each dependency in the pom.xml and make sure the build system runs maven builds after the legacy builds.
Thank you all for your help!

One possibility is to use the system scope to define your dependencies in maven. This allows maven to use the jars downloaded by ivy for its dependencies.
e.g.
<dependencies>
<dependency>
<groupId>group.id</groupId>
<artifactId>artifact</artifactId>
<version>a.b.c</version>
<scope>system</scope>
<systemPath>${basedir}/lib/artifact-a.b.c.jar</systemPath>
</dependency>
...
</dependencies>

Maybe the makepom task will be helpful, it creates a pom from the ivy file.
Example from that page:
<ivy:makepom ivyfile="${basedir}/path/to/ivy.xml" pomfile="${basedir}/path/to/module.pom" conf="default,runtime">
<mapping conf="default" scope="compile"/>
<mapping conf="runtime" scope="runtime"/>
<dependency group="com.acme" artifact="acme-logging" version="1.0" optional="true"/>
</ivy:makepom>

Related

WebLogic client jar

I want to use Java with JMX to monitor WebLogic. I need to use wlclient.jar which is provided into WebLogic lib directory.
Is there any maven repository which I can use to download the wlclient.jar?
The only way that I found is to manually import the jar file into my repository but this is not a option for me.
Another alternative is to create an in-project repository. This makes your project truly portable. This method is similar to the 'Use Dependency with system scope' mentioned by A. Di Matteo, except that it has the added benefit of being able to use any scope (and not just 'system').
I had the same issue as you, using a jar which was not available in Maven Central and after exploring all of the possible options, I settled on the in-project repository which I believe is better that system-scoping a dependency since it frees you to choose the scope.
Steps to do this:
Create a sub-directory called 'lib' in your project
Add this lib as a repository in your pom
<repositories>
<repository>
<id>lib</id>
<name>In Project Repo</name>
<url>file://${basedir}/lib</url>
</repository>
</repositories>
Install the artefact to your lib directory:
mvn install:install-file -Dfile=myArtifact.jar -DgroupId=x.y.z -DartifactId=${artifactId} -Dversion=${version} -Dpackaging=jar -DgeneratePom=true
And, finally use the dependency like you would use any other dependency
<dependencies>
....
<dependency>
<groupId>x.y.z</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
</dependency>
</dependencies>
If you can't find the jar in any Maven repository, you could apply any of the following actions, depending on your needs:
Internal Maven Repository
If you don't have an internal repository (like Artifactory or Nexus), normally used in companies as internal maven cache/proxy/point-of-control, but could also be an option to install it and run it locally.
You could then upload the library there, providing Maven GAV (GroupId, ArtifactId, Version) and make Maven pointing to it as a repository (for your, for your CI server if any, for your colleagues if any). You can then add the library as standard maven dependency.
This solution has longer set-up, but better maintainability.
Install the library in local cache
You could use the Maven Install Plugin and install the library to your local cache, as shown by this official example.
Basically, you could run the following command:
mvn org.apache.maven.plugins:maven-install-plugin:2.5.2:install-file -Dfile=path-to\wlclient.jar -DgroupId=weblogic -DartifactId=wlclient -Dversion=1.0.0 -Dpackaging=jar
It will copy the library to your local Maven cache with standard Maven GAV. However, as above, you should make sure to replicate the same set up on any CI server and any team mate machine as well. You can then add the library as standard maven dependency.
This solution has quicker set-up, but lower maintainability though.
Both solutions however affect the portability of your build (build would fail if someone tries to build it outside of your company network or team).
Use dependency with system scope
You can have the jar as part of your project and point at it via the system scope for that dependency.
<dependency>
<groupId>weblogic</groupId>
<artifactId>wlclient</artifactId>
<version>1.0.0</version>
<systemPath>${basedir}/path/to/library/wlclient-1.0.0.jar</systemPath>
<scope>system</scope>
</dependency>
You should rename the jar though in order to be compliant with Maven conventions.
This solution is more portable, requires much less set-up, but again it needs to be maintained and requires a check-in of the concerned library as part of your versioned project (some may strongly disagree on this practice).

Custom pom.xml filename in Maven multimodule for Tycho

I have a project with a couple of dozen Eclipse plugins, all inter-related and living in different subfolders. The build was converted to a multi-module manifest-first Tycho build a couple of years ago and it works quite well.
One of the plugins is rather key, and can also be built as a standalone Java app, which doesn't use an Eclipse runtime. Currently it has its own POM file (pom-standalone.xml) so that Jenkins can build the standalone app separately and the Tycho build knows nothing about it - the pom-standalone just lists the previously-built plugin jars (thanks Tycho!) and Eclipse libraries that it needs as dependencies. Couple problems with this approach though:
I cannot easily use IntelliJ to work on the standalone project with Maven dependency management, because it doesn't recognize the custom pom-standalone.xml filename as a POM.
The many jars that this project relies on are checked in to the project for the sake of Tycho and the Eclipse Manifest file, but they're also managed by Maven for the standalone build. So any dependencies have to be added to the pom-standalone.xml file AND entered into the OSGi manifest AND checked in to the source control for Eclipse purposes.
It seems like a straightforward workaround would be to tell Tycho/modules to use something other than pom.xml for the submodule's POM, or perhaps all the multimodule POM files, since Eclipse doesn't use those anyway - then the pom-standalone.xml can be converted to pom.xml and then IntelliJ will be fine with it.
I know you can specify the -f attribute to Maven builds, but will that really apply to all submodules? Can you specify the POM filename for just ONE submodule?
Are there alternative solutions? Eclipse/Tycho/p2 builds seem somewhat of a headache requiring manual library management and checking in libraries to source control, but maybe there have been changes I'm not aware of in the Eclipse build world the last few years.
Found a Similar Question that didn't help much.
You can include projects in an aggregator POM by specifying the full name to the POM file with custom name. Example:
<modules>
<module>org.example.bundle1</module>
<module>org.example.bundle2</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
This both works in a pure Maven and Maven/Tycho build.
To extend #oberlies answer a little bit:
SCENARIO: top aggregation POM comes in multiple flavors, so any style can be built from the top.
<!-- in file pom.xml -->
<modules>
<module>org.example.bundle1</module>
<module>org.example.bundle2</module>
<module>org.example.keybundle</module>
</modules>
All submodules will be built using their standard pom.xml
and
<!-- in file pom-tycho.xml -->
<modules>
<module>org.example.bundle1/pom.xml</module>
<module>org.example.bundle2/pom.xml</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
Submodules will be built using the specifically named POM file.
and, likewise:
<!-- in file pom-special.xml -->
<modules>
<module>org.example.bundle1/pom.xml</module>
<module>org.example.bundle2/pom-special.xml</module>
<module>org.example.keybundle/pom-tycho.xml</module>
</modules>
Submodules that have custom POM files use them, and others state they still want the normal POM file, all independent of the name of the top aggregation POM file.
Because mvn -f pom-tycho.xml assumes that file name in all submodules. So if you do want pom.xml in any submodule when the top file isn't named pom.xml you need to fully specify for each submodule.

How to add dependencies to pom.xml in IntelliJ 14

I have a few dependencies in Project Structure/Libraries in IntelliJ 14. How can I add them to my maven pom.xml? There is one single tutorial on IntelliJ's website that does not work for me. I don't want to manage them manually.
The proper way to do this would be to install the dependency artifacts (most likely jars) into your local maven repo, like this.
How to install artifacts to your local maven repo
And then add the dependencies into your pom.xml
<dependencies>
<dependency>
<groupId>com.something</groupId>
<artifactId>artifact</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
Yes, this does require going through each artifact manually, one at a time, but it's a one time setup process.
That is the "proper" way. After that, you can do away with library dependencies in your project structure (they will be picked up correctly via maven).
There is the alternative possibility to "hack" in your project libraries path as a sort of "embedded" maven repo in your project, but that's a little bit hacky and I wouldn't advise that.

How to add resources to the classpath of Maven plugins?

I've got a Maven plugin that depends on slf4j for logging. The default behavior is too chatty for my liking but I can't figure out how to add my logback.xml to the plugin's classpath.
<plugin>
<dependencies>
</dependencies>
</plugin>
allows you to add dependencies to the plugin's classpath, but how do you add local (resource) directories?
You have to wrap your logback.xml into a proper Maven artifact (i.e. a jar) and install it to local repository or deploy to your shared repository, or use systemPath in your dependency declaration to point to a jar placed somewhere inside of your project, which is highly not recommended.
The reason for this is reusability of your build. Think how others would be able to reproduce it.
You don't. You must package them up as an artifact and add it as a dependency.

about generate maven dependency

I am pretty new to maven.
Now I have a maven project developed. My another project needs to depend on this one.
Does anyone know how can I generate my own dependency? So that my second project can add the first one as a dependency in pom.
thank you very much
Since your first project is already a maven-project, just install it in your local repository by running mvn install in the first project's root directory.
Then you can include a dependency in your second project by simply referencing the groupId, artifactId and version you defined in the first project.
So if your first project had the following in its pom:
<project>
<groupId>com.yourdomain</groupId>
<artifactId>yourcomponent</artifactId>
<version>1.0</version>
... <!-- more here -->
you can include this in your second project:
<dependencies>
<dependency>
<groupId>com.yourdomain</groupId>
<artifactId>yourcomponent</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Unless you deploy your project 1 jar to a central maven repository, this will only work if your jar is in your local repository (via mvn install).
Maven projects are identified by the "Maven coordinates", that is, the ArtifactID, GroupID and version.
Say you create your first project and run maven install. Your local repository (in $HOME/.m2/) will now contain the compiled project plus whatever coordinates you put in there.
Your second project must now only depend on the said coordinates.
I would suggest googling a bit on maven. I made a tutorial a long time ago that might help you, even if the examples are a little simple. Here you go and good luck!

Resources