How to force Maven to use local copy of library?

8,258 views
Skip to first unread message

Mike Hearn

unread,
May 31, 2012, 7:30:47 AM5/31/12
to bitc...@googlegroups.com, Gary Rowe
Hi Gary,

Maven question here - right now if you do a maven build in the tools or examples directory, Maven will go and download the library from Nexus instead of using the source in the core/ directory. This is clearly not correct, but I couldn't see an obvious way to make Maven prefer the local copy of the code to the remote copy!

This is causing the new user experience for the library to suck (just went through a few rounds helping somebody just run PingService and this was one of the issues).

Gary Rowe

unread,
May 31, 2012, 9:06:16 AM5/31/12
to bitc...@googlegroups.com
OK, that is strange. I don't have access to BitCoinJ right now so forgive my wanderings and badly formatted examples.

Assuming that they haven't done something peculiar with their local settings.xml then you could try forcing local operations through the -o option which puts Maven into offline mode. For example,

mvn -o clean package

However, this will only stop Maven from looking further than the local repository.

Since the problem seems to be that the local code is not getting picked up then it could be that the reactor build is not sharing artifacts. Assuming that the build is taking place at the command line, then issuing

mvn clean install

at the root of the project should make the entire project build correctly (that is what the build server does all the time). However, to actually execute the code (something like "java PingService") would require that the support libraries are presented on the classpath (something like "java -cp ../core/target/bitcoinj-0.5.jar PingService").

Occassionally IDEs get into tangles with reactor builds and generally a "mvn clean install" operation sorts them out.

If that doesn't sort it out, please come back to me with more details so I can research it better tonight.

Mike Hearn

unread,
May 31, 2012, 9:37:01 AM5/31/12
to bitc...@googlegroups.com
The specific issue can be corrected by running "mvn install" in the core directory whenever you change that code. But what makes actual sense is for the act of doing a "mvn package" or "mvn exec:java" in the tools/ or examples/ directory to rebuild any code from core/ that is necessary. They already depend on it, the problem is that the version of the code in the core/ directory doesn't seem to take precedence over the local or remote repositories when it should.

Does that make the problem clearer?
--

Mike Hearn | Senior Software Engineer |  he...@google.com |  Account security team

Gary Rowe

unread,
May 31, 2012, 10:29:59 AM5/31/12
to bitc...@googlegroups.com
Yes, much. You appear to coming at the problem from the point of view of Maven acting as development environment rather than a build system.

If you make changes to a source file, Maven by itself will not pick that up until you decide to package the enclosing artifact. At that point the new artifact under /target should be detected by "mvn exec:java" and used in preference to local repo.

With IDEs, their internal processes are managing those source code changes and present a coherent environment based on code paths first, then artifacts. This hides the Maven build process unless you always build from a Maven runtime configuration.

Mike Hearn

unread,
May 31, 2012, 10:32:07 AM5/31/12
to bitc...@googlegroups.com
The main issue is that based on a fresh checkout, doing a build of the examples/ directory won't build core/, it'll just download from Nexus which doesn't make a whole lot of sense.

So doing a "mvn package" in core/ is enough, don't need to do an install?

Gary Rowe

unread,
May 31, 2012, 10:43:30 AM5/31/12
to bitc...@googlegroups.com
I would recommend that anyone wanting to run up the examples from the source code should do a reactor install first. The install process ensures that the latest snapshots of the artifacts are shared between modules locally which is "The Maven Way".

$ cd <project root>
$ mvn clean install
$ cd examples
$ mvn exec:java -Dexec.mainClass="com.google.bitcoinj.example.PingService" -Dexec.args="arg0 arg1 arg2"

Should do the trick (untested at my end, though)
Reply all
Reply to author
Forward
0 new messages