2

why use Maven when you have such quantity of local jars?

So we have a client that have a lot of private jars and custom jars. For example commons-langMyCompanyCustom.jar which is commons-lang.jar with 10 more classes in it.

So on their environment we use 100% Maven without local dependencies. But on our site we have the jars for development in Eclipse and have Maven build with the public ones, but we do not have permission to add their jars in our organizational repository.

So we want to use the Maven good things like: compile,test, build uber-jar, add static code analysis, generate java-docs, sources-jars etc. not to do this thinks one by one with the help of Eclipse.

So we have 70 jar some of them are public if I get the effective pom on their environment I found 50 of them in Maven Central, but the other 20 are as I called "custom" jars. I searched for decision of course but found this:

<dependency>
    <groupId>sample</groupId>
    <artifactId>com.sample</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/src/main/resources/yourJar.jar</systemPath>
</dependency>

So for all 20 of them I have to add this in the development maven profile?? Is there a easy way like in Gradle where you can add all folder with its dependencies to the existing ones?

Also installing one by one in every developer's repo is not acceptable.

Xelian
  • 16,680
  • 25
  • 99
  • 152
  • Can you combine them into a library? – PM 77-1 May 10 '16 at 19:45
  • NOO PLEASE NOO. Don't use the `system` scope... just don't do it. *Also installing one by one in every developer's repo is not acceptable.*, yes that is a valid concern. You should use a repository manager, like Nexus or Artifactory. You can then upload them all once and every developer will download them from there. See also http://stackoverflow.com/a/2230464/1743880 – Tunaki May 10 '16 at 19:47
  • As @Tunaki said, please don't do `system` scope. Your easiest path _might_ be to build a script that installs all the custom JARs into your local repo as a set of calls to the `install:install-file` task. But that would suck. Stand up a private instance of [Sonatype Nexus OSS](http://www.sonatype.org/nexus/downloads/) and point everyone to that, proxying to central (which it does out of the box). If you're doing real development with the JVM and you don't want to deal with downtime, you need a proxy manager no matter what build tool you're using. – Mykel Alvis May 10 '16 at 19:51
  • Have a look at [MavenHoe](https://github.com/OndraZizka/MavenHoe), I wrote it for these purposes. It's a bit of hack but might serve your purpose. – Ondra Žižka May 10 '16 at 22:27
  • Hello @Xelian any updates? – CMPSoares May 12 '16 at 18:32

3 Answers3

2

Please forget the system scope as mentioned before! Too problematic...

Ideally:

Ideally, all your developers have access to Repository Manager in your or their organization (if possible).

A central environment for your System Integration Testing, maybe?

Alternatively, you may have a central environment for testing where all the dependencies are provided. This approach can be used to simulate how a compilation would work as if it's in your client's environment. Plus you only setup jars once.

So on their environment we use 100% Maven without local dependencies. But on our site we have the jars for development in Eclipse and have Maven build with the public ones, but we do not have permission to add their jars in our organizational repository.

According to what you're saying in the above-quoted excerpt I believe you want to have set in your build's pom.xml assuming that in the client setup the dependencies will be present.

Especially, as you indicate that the organization doesn't give you permission to add their jars in your repository, I would use the provided scope.

As stated in the Maven docs, the definition of a provided dependency is as followed:

This is much like compile, but indicates you expect the JDK or a container to provide the dependency at runtime. For example, when building a web application for the Java Enterprise Edition, you would set the dependency on the Servlet API and related Java EE APIs to scope provided because the web container provides those classes. This scope is only available on the compilation and test classpath, and is not transitive.

So basically you assume that these dependencies will be present at your client's setup. However, this has some limitations. Meaning you can build solutions independently but cannot test it locally because you won't have the dependencies on your workstation.

If you won't even have access to the jars to configure your central environment ask if your client can provide a DEV/SIT environment.

None of the above? Inherit a parent pom.

To avoid the whole constant copy-paste process for every single (related) project, maven has the tools to centralize dependency and plugin configurations, one of such is by inheriting the configuration of a parent pom. As is explaining in the following documentation it is quite simple:

  • First you create a project with just a pom.xml where you define everything you wish to centralize (watch out, certain items have slight differences in their constructs);
  • Use as property of packaging tag the option pom: <packaging>pom</packaging>;
  • In the pom's that have to inherit these configurations set the parent configuration tags in <parent> ... </parent> (documentation is very clear with this);
  • Now everytime you update any "global" pom configuration only the parent version has to be updated on every project. As a result of this, you only need to configure everything once.

You can also apply this together with the abovementioned solutions, this way combining to find a solution that fits best to your needs.

But there is a big Maven world out there, so I advise a good read in its doc's to further acknowledge your possibilities. I remembered these situations because I've been in a similar situation you seem to be now.

Good luck!

CMPSoares
  • 4,175
  • 3
  • 24
  • 42
1

TL;DR: MavenHoe creates a Maven repository server (not a directory) which serves the artefacts from a directory, guessing what you ask for if needed. The purpose is to avoid complicated version synchronizing - it simply takes whatever is closest to the requested G:A:V.

I have moved the MavenHoe project, which almost got lost with the decline of Google Code, to Github. Therefore I put it here for availability in the form of a full answer:

One of the options you have when dealing with conditions like that is to take whatever comes in form of a directory with .jar's and treat it as a repository.

Some time ago I have written a tool for that purpose. My situation was that we were building JBoss EAP and recompiled every single dependency. That resulted in thousands of .jars which were most often the same as their Central counterpart (plus security and bug fixes).

I needed the tests to run against these artifacts rather than the Central ones. However, the Maven coordinates were the same.

Therefore, I wrote this "Maven repository/proxy" which provided the artifact if it found something that could be it, and if not, it proxied the request to Central.

It can derive the G:A:V from three sources:

  1. MANIFEST.MF
  2. META-INF/.../pom.xml
  3. Location of the file in the directory, in combination with a configuration file like this:

    jboss-managed.jar      org/jboss/man/             jboss-managed      2.1.0.SP1     jboss-managed-2.1.0.SP1.jar
    getopt.jar             gnu-getopt/                getopt             1.0.12-brew   getopt-1.0.12-brew.jar
    jboss-kernel.jar       org/jboss/microcontainer/  jboss-kernel       2.0.6.GA      jboss-kernel-2.0.6.GA.jar
    jboss-logging-spi.jar  org/jboss/logging/         jboss-logging-spi  2.1.0.GA      jboss-logging-spi-2.1.0.GA.jar
    ...
    

The first column is the filename in the .zip; Then groupId (with either slashes or dots), artifactId, version, artifact file name, respectively.

Your 70 files would be listed in this file.

See more information at this page:

https://rawgit.com/OndraZizka/MavenHoe/master/docs/README.html

The project is available here.
Feel free to fork and push further, if you don't find anything better.

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
  • We do this with the parent configuration to indicate the central and have a local repo where all dependencies are saved plus the ones I compile using "mvn install XYZ". But the later is configured in the global settings.xml using the tag. Although this might. – CMPSoares May 11 '16 at 00:46
1

Another alternative is the project RepoTree.

This one creates a Maven repository directory (not a server) from another directory which contains just the .jars. In other words, it creates the necessary .pom files and directory structure. It takes into account only the precise information from metadata contained in the archives (MANIFEST.MF, pom.xml).

Utility to recursively install artifacts from a directory into a local Maven repository Based on Aether 1.7

This is 5 years old, but still should work fine.

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
  • Nice didn't know this one! :-) Is it still being updated? – CMPSoares May 11 '16 at 00:33
  • Hardly :) But Karel will be glad if you send him a "Thank you" :) Look for kpiwko at Red Hat – Ondra Žižka May 11 '16 at 00:46
  • Thank. Karel is all over place. Thanks for the reference. :-) – CMPSoares May 11 '16 at 01:01
  • Right, once you start working with Maven or Arquillian, you can't miss Karel :) But actually not at SO I see – Ondra Žižka May 11 '16 at 01:02
  • 1
    Haven't tried Arquillian yet but work with Maven, Nexus and Redhat at a daily basis for over a year now and didn't give much attention to the community. I'm a newbie but it is always nice to get to know people who share similar interests. :-) – CMPSoares May 11 '16 at 01:08
  • You are a newbie at the right time, everything around Maven is getting quite stable and less buggy. Good luck & enjoy :) – Ondra Žižka May 11 '16 at 01:19
  • Thank you very much Ondra! :-) – CMPSoares May 11 '16 at 01:21
  • OK but if I install them how to reference them in the pom.xml , How to describe them? I have to do one by one adding od the dependencies, but more of my jars are transitive, if we do not have pom for them in the local repo then maven will not be able to find them. And even installed locally I have to add 20 dependency maven pom tags. – Xelian May 11 '16 at 07:26
  • @Xelian haven't used RepoTree practically, but I assume it might create some kind of `pom.xml` listing all artefacts in the directory, and you may copy & paste from that to your `pom.xml`. If it doesn't, then you can figure out the Maven coordinates from the .jar paths or from the `pom.xml` next to the `.jar`'s. – Ondra Žižka May 11 '16 at 08:39