chrisdchristo / capsule-maven-plugin

Capsule Maven Plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Dependencies missing for subprojects

balbusm opened this issue · comments

I'm having problem with generating capsule for subprojects.
I have project A and project B.
Project A depends on project B.
I'm trying to include project B into A as described in #28.
The problem is that at runtime I'm missing dependencies for project B.
It happens because at compile time only dependencies for project A are put into manifest and at runtime there is no way to resolve dependencies to project B.

Is project B listed as a dependency of project A? If so, then Capsule should resolve project B and its dependencies at runtime. Perhaps provide an example project I can play with.

See example project
https://github.com/balbusm/nestedprojects
Once you build. See manifest in projectb fat jar. Running fat jar causes exception hence it is missing H2 dependency.

Hmm so essentially you want the dependencies to be embedded (without the transitive dependencies) and then the transitive dependencies to be resolved at runtime? There might be an issue with this - puniverse/capsule#102

I want to add dependencies that are built along with Project B, so it would be Project A in the given example. I don't want to add dependencies available in maven central.
It has nothing to do with transitive dependencies.
If I have Project C that is depended on Project A, I would like also add it to the capsule jar. However I don't want to add H2 dependency as it is not part of my project.

Pull request works in this way. It packages Project B, Project A and Project C. It also adds all dependencies of those projects on the "Dependency" entry in manifest.

Well regardless if they are modules or whatever, the idea is to have some dependencies (I guess here you only want the submodules) to be embedded in the built capsule and also these dependencies should be embedded without their dependencies (also known as transitive dependencies).

The question I need to know is, does Capsule have to resolve the transitive dependencies or will you or Reactor provide these transitive dependencies? Otherwise Capsule will fail to run as it does not have these transitive dependencies in the classpath.

During the run Capsule needs to resolve transitive dependencies. They shouldn't be embed.

Answering your question: Reactor should provide names of transitive dependencies. Having sibling projects is very common, configuration in this case should be reduced to minimum.

Example how this should work. Project A depends on B. B is sibling project. I'm building capsule for A. See dependency tree:

            A
          /   \
         B     D  
        /       \
       E      C v2
      /    
   Cv1     

Once we put dependencies to Capsule it should be:
Dependencies: E, Cv2, D

Yep understood. Since Capsule has to resolve the transitive dependencies at runtime, these need to be listed in the Dependencies manifest entry. The problem with Capsule (specifically capsule-maven), is that even if you list a dependency in the Dependencies but have that dependency embedded already in the capsule jar, then its transitive dependencies won't be resolved. So in your example, if we list project B in the Dependencies manifest entry but also include the project B jar in the capsule jar then, all of project B's dependencies will not be resolved. One solution to this is to have capsule-maven scan the embedded jars (such as project B) and read their pom.xml files to read their dependency list. So for example reading project B's pom.xml file we'll get a list of all its dependencies (i.e the transitive dependency information) we need to be able to resolve everything. See the progress of this here.

Of course it might be the case that an embedded jar might not have a pom.xml and thus we won't have any transitive dependency info.

So the most effective solution is to have the maven plugin resolve all the required dependencies (and transitive dependencies) needed and list them exhaustively in the Dependencies manifest entry. This will guarantee that Capsule will have all the necessary info to download/resolve all required artifacts needed for the capsule to run (minus any already embedded). This solution will also make sure only the latest version of an artifact is listed (so in your example, only Cv2 is listed and not Cv1).

First solution looks a bit too complex to me and requires changes in capsule-maven. I would go with modified second option. You put on the Dependencies only direct dependencies for projects A, B. So in the given example I should be D, E. capsule-maven should resolve at runtime which version of C should be used. According to maven documentation it should be Cv2 not because it's latest but because it's the nearest definition. Notice that order of dependencies matters, so it has to be D,E. If you put E,D then Cv1 will be used.
See another example:

            A
          /   \
         D     B  
        /       \
       Cv1      Cv2

A and B are sibling projects. In this case Dependencies should contain D and Cv1, because Cv1 is the nearest version.

Agree that solution 2 is better, but if we have both even better. Check out latest version (1.1.1), we've changed a few things around to make building capsules easier.

Note that capsule-maven has a new release 1.0.2 which does solution 1. Also there is a new release of the plugin 1.1.2 which does solution 2.

Thanks for all your help! You should be able to do what you desire by utilising the various includeXYZ and resolveXYZ flags.

See more info on scopes here that you might find useful!