Deploying only some of the dependencies with maven

2019-07-28 16:25发布

问题:

I have a problem that I do not know how solve it properly. I'm developing plugins for a program that loads these plugins dynamically on start up. Everything worked out very well so far as I usually only do use dependencies like Apache Commons which have been used by the main program, too.

Now I tried to play around with Google Guice and the main program does not have the package in the class path and so there is a NoClassDefFoundError at start up of course. I used google for a while to find a solution to my problem but the only thing I came up with was using an uber jar. The problem with that is, that I do have dependencies to other plugins that I use and I don't want to pull them in my plugin as I would end up having to manage all of them. It might even happen that I have two different implementations in the class path because I lost track and did not update that minor version. Unfortunately there is usually no interface for other plugins so I cannot take that in.

Long text, short question: is it possible to tell Maven to only pull Guice in the file or, even better, is there a cleaner solution to this problem? Maybe I even did miss something crucial in the whole process? Any help is appreciated.

回答1:

I just found a solution that works. Using the shade plugin like this yields the needed results:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <artifactSet>
                    <includes>
                        <include>com.google.inject:guice</include>
                    </includes>
                </artifactSet>
            </configuration>
        </execution>
    </executions>
</plugin>


回答2:

As the classpath of main program doesn't jave Guice jar, the parent classloader doesn't load Guice package. If a child classloader is loading the Guice jar then main program won't have any knowledge of it. Now to tackle this problem you can do either of below :

  • Move Guice jar to the classpath of your main program
  • Moe the portion of code which is using Guice jar to child classloader (plugin)