2

I run an open source library and am considering having it fully embrace Maven and upload it to to a central repository so that people can easily add it to their projects.

The problem is that it depends on a couple of older libraries that do not exist on any Maven repos. Currently, that means a pom file has to use the system scope of the dependency. I've also read about creating a local repository for the project to install the 3rd party libraries.

However, my impression is that neither of these approaches will work well when I deploy my library to a Maven repository. That is, if it depends on external "system" or local repositories, then when someone adds my library to their pom file, they're not actually done. They also have to download the 3rd party libraries and manually install them or add them to their own local repository.

What I'd like to have happen is for these couple of 3rd party libraries to simply be included in the jar file that I deploy to the central repository. That way, if someone adds my library to their pom file, they really are done and don't have to worry about getting and installing the 3rd party libraries. Is it possible to do that?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
James
  • 85
  • 5
  • 2
    Under which license are the 3rd party libs? Maybe you can attach them to your upload (http://www.mojohaus.org/build-helper-maven-plugin/attach-artifact-mojo.html) or upload them separately with their own POMs to model the dependency graph correctly. – Brian Mar 23 '16 at 21:55
  • They're some flavor of free. (GNU or something of the like) – James Mar 23 '16 at 23:11

1 Answers1

1

First off, I'll start by saying that you should back away as far as possible from the system scope. You can refer to this answer for more information.

A way to circumvent your problem is indeed to include in the deployed JAR all the libraries that aren't present in Maven Central. (Let's say you have installed those libraries in your local repository.) You can do that with the maven-shade-plugin, which is a plugin used to create uber jars. The attribute artifactSet controls what will be included in the shaded JAR. In the following snippet, only the two dependencies groupId:artifactId and groupId2:artifactId2 will be included.

<plugin>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.3</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <artifactSet>
          <includes>
            <include>groupId:artifactId</include>
            <include>groupId2:artifactId2</include>
          </includes>
        </artifactSet>
      </configuration>
    </execution>
  </executions>
</plugin>

By default, the shaded JAR will replace your main artifact and this will be the JAR that will be deployed. The POM that will be deployed will not contain the dependency entries for the artifacts that were included in the shaded JAR, as such, a client depending on your deployed artifact won't be transitively-depending on them.

Community
  • 1
  • 1
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 1
    That's the solution I was also going to propose as well. Additionally, I would also suggest to place the `bundle` keyword in the dependency artifactId (like `-bundle`), to make it clear that you are providing more than a simple artifact to consumers (which would not be surprised to see a large jar then or to find several package-sets within the jar). Although there will be no non-bundle version of this library, it would still make sense imho. – A_Di-Matteo Mar 23 '16 at 22:39
  • Thanks. While I haven't verified that your answer works, what you say sounds like exactly what I need! – James Mar 23 '16 at 22:46
  • Actually, one more follow up question. Does this mean I should install the 3rd parties to my local repo first? I imagine if they're not the shade include by group-id and artifact id wouldn't be meaningful. Is that right? – James Mar 23 '16 at 22:51
  • @James That is correct. You should install them first into your local repo and declare the dependencies like you usually would. – Tunaki Mar 23 '16 at 22:53