1

I have two maven Projects call them as MainProject and DependnecyProject. I use DependnecyProject functions in the MainProject project which means DependnecyProject is a dependency for MainProject Project.

MainProject pom.xml

    <dependency>
        <groupId>testgroup</groupId>
        <artifactId>DependnecyProject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <scope>compile</scope>
    </dependency>

In my local eclipse, this is completely perfect and the execution doesn't have any problem.

I have both of these Projects in Git and I have two Jobs created in Jenkins named Main and Dependency. I have a Pre Step in the Main job to build the Dependency first and then build Main.

Dependency job is successful but the Main job is failing saying the dependency mentioned above (DependnecyProject) cannot be resolved. This can be understood as the Jenkins and Maven is not able to find the dependency. Is there a way to make sure the Jenkins resolve the dependency?

Alternately, I have tried one more solution In My Local, I have tried to use in MainProject POM.XML

    <dependency>
        <groupId>testgroup</groupId>
        <artifactId>DependnecyProject</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <scope>system</scope>
        <systemPath>C:\Users\cpratap\New-Workspace\Child\target\Parent-0.0.1-SNAPSHOT.jar</systemPath>
    </dependency>

which is working perfectly in local, but not sure how to make it work the same in the Jenkins?

Update: In the Jenkins Main job, I did below configuration (as suggested by @Ian W). Though it is a poor work around as mentioned, this really worked.

  1. Followed the same configuration
  2. In the Main Jenkins job, I have three Pre-Steps
  3. One Pre-Step is to trigger the Dependency Job
  4. Second Pre-Step is to copy the artifacts from Dependency to Main
  5. Third Pre-Step is to install the Dependency into the local repo using "Invoke Top Level Maven Targets" and used below in Goal install:install-file -Dfile= -DgroupId= -DartifactId= -Dversion= -Dpackaging=jar

This completely solved my problem and I could run the build and run my test cases without any issues. Thank you all for the support

Pratap
  • 63
  • 4
  • 1
    Can you show how the maven jobs look like? The artifact (jar) must be available in the local repository, otherwise the main project build will always fail. I see the jar of dependency project is created, so the main project can point to it, and that's why it succeeds when using the second case where you define the full path. Did you at least define "install" goal in DependencyProject Maven job? – Marco Tizzano May 15 '21 at 09:55
  • 2
    Usually, you use a Maven repository manager where you _deploy_ your artifacts to. That way, no environment is forced to _install_ dependencies first. – Seelenvirtuose May 15 '21 at 09:58
  • @Seelenvirtuose That's right. However, he defined two different jobs, launched separately, that means that the main project's build must have somehow all dependencies available to succeed, and one way to do that they have to be installed in the local repository. – Marco Tizzano May 15 '21 at 10:04
  • Use a repository manager. Don't try to share local repositories between builds, they are not thread safe. – J Fabian Meier May 15 '21 at 10:10
  • @MarcoTizzano That is one way to do it, but not a good one. Each developer - for example - that checks out the main project has to do these setup steps first, which is not appropriate. – Seelenvirtuose May 15 '21 at 10:14
  • 1
    The two jobs must both use the same node/agent and not a private repo. The first job must use target "install" to publish to the local repo. You should not need to specify "scope" or "systemPath". But a proper repo mgr is preferred. – Ian W May 15 '21 at 10:17
  • @Seelenvirtuose yes i am aware and I agree that the best practice would be to use a repository manager. However, the question was another, and it is focused on Maven, not an additional tool. I just want to answer the question and help to sort the issue out. Of course, if he wants to use a repositoty manager, that it's even better. – Marco Tizzano May 15 '21 at 10:18
  • @IanW you got exactly what I meant to do :) – Marco Tizzano May 15 '21 at 10:20
  • 1
    A (poor) workaround would be to have the provider job archiveArtifacts. The consumer job can use [copyartifact plugin](https://plugins.jenkins.io/copyartifact/) to retrieve into workspace, then [mvn install:install-file](https://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html) to add to the local repo. – Ian W May 15 '21 at 10:29
  • Don't use system scope. Are the two projects in any way related on the file system level, or do you have two checkouts in Eclipse in the same workspace? – Thorbjørn Ravn Andersen May 16 '21 at 01:00

1 Answers1

-2

If you put a jar in vcs along with you source code, then the way to do that is to declare you repository in you pom.xml file, and use you jar as a dependency.

For example, if you put your jar to lib directory of you projects, that's how you use it in you project. Suppose you jar name is hello-world-library-1.0-SNAPSHOT.jar, you want your groupId to be com.local , your artifactId hello-world-library-local and version is 1.0-SNAPSHOT

First you should create local repository in your project's directory and put your jar there.

mvn \
deploy:deploy-file \
-Durl=file:./lib \
-Dfile=hello-world-library-1.0-SNAPSHOT.jar \
-DgroupId=com.local \
-DartifactId=hello-world-library-local \
-Dpackaging=jar \
-Dversion=1.0-SNAPSHOT

Then add local repository to you pom.xml

<repositories>
    <repository>
        <id>localrep</id>
        <name>local repository</name>
        <url>file:${project.basedir}/lib</url>
    </repository>
</repositories>

And then, add you jar as a dependency to dependencies block in your pom.xml file

    <dependencies>
        <dependency>
            <groupId>com.local</groupId>
            <artifactId>hello-world-library-local</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

You can use that if you want to distribute you jar with your source code and don't want to mess with your project's setting every time you're building on a new machine.

But this is not recommended to use in enterprise environment. You NEVER put repository block in your pom.xml, unless that's your toy project, or your really know what you are doing

If you don't want to copy your jar to your project's directory every time, you should consider converting your projects to a single multi module maven project.

Ilya Sazonov
  • 1,006
  • 10
  • 16
  • 1
    Adding a binary to a repo is a really bad idea, especially if part of a CI build job. It will blow up the size of yout repo size since every binary commit is a whole new copy. Modify 1 char in your source add x MB to your repo. Heck, every build would add an identical copy w/new MANIFST.MF w/updated timestamp! Also, a milti-module maven project suggests OP'd always build both all the time, when it's probably not the intent. With respect, checking in binaries is an anti-pattern and should never be recommended; that's how bad practices are born and perpetuated. Suggest deleting answer. – Ian W May 15 '21 at 10:42
  • That's all true, if you update your jar every time you build your project. But if you do it rarely, the problem with new copies of the binary for every commit doesn't exist. And for toy projects it's fine, because it teaches you how to decompose your code leaving the burden of working with artifact repository. Never do it in production though. If you need to update the library frequently, multi maven project is way. So if after reading that ,you still think I should delete my answer, I will gladly do so – Ilya Sazonov May 15 '21 at 13:24
  • @IanW This is why reproducible builds are good, and Maven has been taught to do them - http://maven.apache.org/guides/mini/guide-reproducible-builds.html – Thorbjørn Ravn Andersen May 16 '21 at 01:10