Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A layout for maven project with a patched dependency

Tags:

maven-2

patch

Suppose, I have an opensource project that depends on some library, that must be patched in order to fix some issues. How do I do that? My ideas are:

  1. Have that library sources set up as a module, keep them in my vcs. Pros: simple. Cons: some third party sources in my repo, might slow down build process, hard to find a patched place (though can be fixed in README)
  2. Have a module, like in 1, but keep patched source files only, compile them with orignal library jar in classpath and somehow replace *.class files in library jar on build. Pros: builds faster, easy to find patched places. Cons: hard to configure, that jar hackery is non-obvious (library jar in repository and in my project assembly would be different)
  3. Keep patched *.class files in main/resources, and replace on packaging like in 2). Pros: almost none. Cons: binaries in vcs, hard to recompile a patched class as patch compilation is not automated.

One nice solution is to create a distinct project with patched library sources, and deploy it on local/enterprise repository with -patched qualifier. But that would not fit for an opensourced project that is meant to be easily buildable by anyone who checks out its sources. Or should I just say "and also, before you build my project, please check out that stuff and run mvn install".

like image 551
zamza Avatar asked Apr 12 '10 00:04

zamza


People also ask

How do you add dependencies in the Maven project?

Add a Java Maven Dependency to the Utility ProjectRight-click the utility project, and select Maven>Add Dependency. Type a dependency name in the Enter groupID… field (e.g., commons-logging) to search for a dependency. Select the dependency, and click OK.

How does Maven work with dependencies?

Maven includes a dependency with this scope in the runtime and test classpaths, but not the compile classpath. This scope indicates that the dependency is not required for normal use of the application, and is only available for the test compilation and execution phases. This scope is not transitive.


2 Answers

One nice solution is to create a distinct project with patched library sources, and deploy it on local/enterprise repository with -patched qualifier. But that would not fit for an opensourced project that is meant to be easily buildable by anyone who checks out its sources. Or should I just say "and also, before you build my project, please check out that stuff and run mvn install".

This is what I would do (and actually what I do) for both a corporate and an opensource project. Get the sources, put them under version control in a distinct project, patch them, rebuild the patched library (and include this information in the version, something like X.Y.Z-patched), deploy it to a repository (you could use SVN for this, a la Google Code1), declare the repository in your POM and update the dependency to point on your patched version.

With this approach, you can say to your users: check out my code and run mvn install and they will just get the patched version without any extra action. This is IMHO the cleanest way (not error prone, no class path order mess, no increase of the build time, etc).

1 Lots of people are deploying their code to their hosted subversion repository (how-to in this post).

like image 155
Pascal Thivent Avatar answered Sep 21 '22 07:09

Pascal Thivent


One nice solution is to create a distinct project with patched library sources, and deploy it on local/enterprise repository with -patched qualifier. But that would not fit for an opensourced project that is meant to be easily buildable by anyone who checks out its sources. Or should I just say "and also, before you build my project, please check out that stuff and run mvn install".

I'd agree with this and Pascal's answer. Some additional notes:

  • you may use dependency:unpack on the original artifact and then combine that with your compiled classes if you don't want to rebuild the whole dependant project
  • in either case, your pom.xml will need to correctly represent the dependencies of that library
  • you can still integrate this as part of your project's build to avoid the 'deploy to a repository' step
  • make sure you honour the constraints of the project's license when doing all this!
like image 37
Brett Porter Avatar answered Sep 22 '22 07:09

Brett Porter