Can I add jars to maven 2 build classpath without installing them?

前端 未结 24 2579
萌比男神i
萌比男神i 2020-11-22 01:41

Maven2 is driving me crazy during the experimentation / quick and dirty mock-up phase of development.

I have a pom.xml file that defines the dependenc

相关标签:
24条回答
  • 2020-11-22 01:57

    What works in our project is what Archimedes Trajano wrote, but we had in our .m2/settings.xml something like this:

     <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://url_to_our_repository</url>
     </mirror>
    

    and the * should be changed to central. So if his answer doesn't work for you, you should check your settings.xml

    0 讨论(0)
  • 2020-11-22 01:57

    The solution for scope='system' approach in Java:

    public static void main(String[] args) {
            String filepath = "/Users/Downloads/lib/";
            try (Stream<Path> walk = Files.walk(Paths.get(filepath))) {
    
            List<String> result = walk.filter(Files::isRegularFile)
                    .map(x -> x.toString()).collect(Collectors.toList());
    
                    String indentation = "    ";
                    for (String s : result) {
                        System.out.println(indentation + indentation + "<dependency>");
                        System.out.println(indentation + indentation + indentation + "<groupId>"
                                + s.replace(filepath, "").replace(".jar", "")
                                + "</groupId>");
                        System.out.println(indentation + indentation + indentation + "<artifactId>"
                                + s.replace(filepath, "").replace(".jar", "")
                                + "</artifactId>");
                        System.out.println(indentation + indentation + indentation + "<version>"
                                + s.replace(filepath, "").replace(".jar", "")
                                + "</version>");
                        System.out.println(indentation + indentation + indentation + "<scope>system</scope>");
                        System.out.println(indentation + indentation + indentation + "<systemPath>" + s + "</systemPath>");
                        System.out.println(indentation + indentation + "</dependency>");
                    }
    
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:59

    For throw away code only

    set scope == system and just make up a groupId, artifactId, and version

    <dependency>
        <groupId>org.swinglabs</groupId>
        <artifactId>swingx</artifactId>
        <version>0.9.2</version>
        <scope>system</scope>
        <systemPath>${project.basedir}/lib/swingx-0.9.3.jar</systemPath>
    </dependency>
    

    Note: system dependencies are not copied into resulted jar/war
    (see How to include system dependencies in war built using maven)

    0 讨论(0)
  • 2020-11-22 01:59

    I alluded to some python code in a comment to the answer from @alex lehmann's , so am posting it here.

    def AddJars(jarList):
      s1 = ''
      for elem in jarList:
       s1+= """
         <dependency>
            <groupId>local.dummy</groupId>
            <artifactId>%s</artifactId>
            <version>0.0.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/manual_jars/%s</systemPath>
         </dependency>\n"""%(elem, elem)
      return s1
    
    0 讨论(0)
  • 2020-11-22 02:00

    A strange solution I found:

    using Eclipse

    • create simple (non-maven) java project
    • add a Main class
    • add all the jars to the classpath
    • export Runnable JAR (it's important, because no other way here to do it)
    • select Extract required libraries into generated JAR
    • decide the licence issues
    • tadammm...install the generated jar to your m2repo
    • add this single dependency to your other projects.

    cheers, Balint

    0 讨论(0)
  • 2020-11-22 02:01

    Problems of popular approaches

    Most of the answers you'll find around the internet will suggest you to either install the dependency to your local repository or specify a "system" scope in the pom and distribute the dependency with the source of your project. But both of these solutions are actually flawed.

    Why you shouldn't apply the "Install to Local Repo" approach

    When you install a dependency to your local repository it remains there. Your distribution artifact will do fine as long as it has access to this repository. The problem is in most cases this repository will reside on your local machine, so there'll be no way to resolve this dependency on any other machine. Clearly making your artifact depend on a specific machine is not a way to handle things. Otherwise this dependency will have to be locally installed on every machine working with that project which is not any better.

    Why you shouldn't apply the "System Scope" approach

    The jars you depend on with the "System Scope" approach neither get installed to any repository or attached to your target packages. That's why your distribution package won't have a way to resolve that dependency when used. That I believe was the reason why the use of system scope even got deprecated. Anyway you don't want to rely on a deprecated feature.

    The static in-project repository solution

    After putting this in your pom:

    <repository>
        <id>repo</id>
        <releases>
            <enabled>true</enabled>
            <checksumPolicy>ignore</checksumPolicy>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <url>file://${project.basedir}/repo</url>
    </repository>
    

    for each artifact with a group id of form x.y.z Maven will include the following location inside your project dir in its search for artifacts:

    repo/
    | - x/
    |   | - y/
    |   |   | - z/
    |   |   |   | - ${artifactId}/
    |   |   |   |   | - ${version}/
    |   |   |   |   |   | - ${artifactId}-${version}.jar
    

    To elaborate more on this you can read this blog post.

    Use Maven to install to project repo

    Instead of creating this structure by hand I recommend to use a Maven plugin to install your jars as artifacts. So, to install an artifact to an in-project repository under repo folder execute:

    mvn install:install-file -DlocalRepositoryPath=repo -DcreateChecksum=true -Dpackaging=jar -Dfile=[your-jar] -DgroupId=[...] -DartifactId=[...] -Dversion=[...]
    

    If you'll choose this approach you'll be able to simplify the repository declaration in pom to:

    <repository>
        <id>repo</id>
        <url>file://${project.basedir}/repo</url>
    </repository>
    

    A helper script

    Since executing installation command for each lib is kinda annoying and definitely error prone, I've created a utility script which automatically installs all the jars from a lib folder to a project repository, while automatically resolving all metadata (groupId, artifactId and etc.) from names of files. The script also prints out the dependencies xml for you to copy-paste in your pom.

    Include the dependencies in your target package

    When you'll have your in-project repository created you'll have solved a problem of distributing the dependencies of the project with its source, but since then your project's target artifact will depend on non-published jars, so when you'll install it to a repository it will have unresolvable dependencies.

    To beat this problem I suggest to include these dependencies in your target package. This you can do with either the Assembly Plugin or better with the OneJar Plugin. The official documentaion on OneJar is easy to grasp.

    0 讨论(0)
提交回复
热议问题