Programmatically resolving Maven dependencies outside of a plugin - get RepositorySystemSession and RepositorySystem

前端 未结 6 692
Happy的楠姐
Happy的楠姐 2020-12-24 08:55

Maybe this is going to be a larger task than I had originally thought, but regardless, I\'m trying to load a MavenProject from a file and then resolve its depen

相关标签:
6条回答
  • 2020-12-24 09:21

    Try jcabi-aether, which is a wrapper around Apache Aether from Sonatype:

    final File repo = this.session.getLocalRepository().getBasedir();
    final Collection<Artifact> deps = new Aether(this.getProject(), repo).resolve(
      new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
      JavaScopes.RUNTIME
    );
    

    If you are outside of Maven plugin:

    final File repo = new File(System.getProperty("java.io.tmpdir"), "my-repo");
    final MavenProject project = new MavenProject();
    project.setRemoteArtifactRepositories(
      Arrays.asList(
        new RemoteRepository(
          "maven-central",
          "default",
          "http://repo1.maven.org/maven2/"
        )
      )
    );
    final Collection<Artifact> deps = new Aether(project, repo).resolve(
      new DefaultArtifact("junit", "junit-dep", "", "jar", "4.10"),
      JavaScopes.RUNTIME
    );
    
    0 讨论(0)
  • 2020-12-24 09:21

    This is covered in "Aether/Setting Aether Up" for the RepositorySystem and in "Aether/Creating a Repository System Session" in the eclipse wiki.

    There is not a ton of documentation, but you can create a RepositorySystem as follows:

    // verbatim copy from the Setting Aether Up link
    private static RepositorySystem newRepositorySystem()
    {
        DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
        locator.addService( TransporterFactory.class, FileTransporterFactory.class );
        locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
    
        return locator.getService( RepositorySystem.class );
    }
    

    Do note that this requires the dependencies detailed in "Getting Aether", most notably maven-aether-provider.

    When you have your repository system the tutorial goes on to create a RepositorySystemSession with the following factory method:

    // copied verbatim from "Creating a Repository System Session"
    private static RepositorySystemSession newSession( RepositorySystem system )
    {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
    
        LocalRepository localRepo = new LocalRepository( "target/local-repo" );
        session.setLocalRepositoryManager( system.newLocalRepositoryManager( session, localRepo ) );
    
        return session;
    }
    
    0 讨论(0)
  • 2020-12-24 09:22

    I would recommend to read the information about Aether lib which is exactly is for such kind of purposes.

    Note: Aether was previousely developed at Sonatype, but has since moved to Eclipse.

    0 讨论(0)
  • 2020-12-24 09:24

    There is a nice set of standalone examples for Eclipses Aether API which is used in the latest Maven (3.1.1) and it can be found here.

    Note: Maven 3.1.X still uses Aether 0.9.0.M2 (and the latest version which us used in the examples is 0.9.0.M3). So to run these examples inside a Maven plugin, version M2 is required, and a standalone application can use the latest M3 version.

    0 讨论(0)
  • 2020-12-24 09:26

    Try this (as can be seen from the ather-demo):

    ...
    LocalRepository localRepository = new LocalRepository("/path/to/local-repo");
    
    RepositorySystem system = getRepositorySystemInstance();
    RepositorySystemSession session = getRepositorySystemSessionInstance(system, localRepository);
    ....
    
    public static RepositorySystem getRepositorySystemInstance()
    {
        /**
         * Aether's components implement org.sonatype.aether.spi.locator.Service to ease manual wiring and using the
         * prepopulated DefaultServiceLocator, we only need to register the repository connector factories.
         */
        MavenServiceLocator locator = new MavenServiceLocator();
        locator.addService(RepositoryConnectorFactory.class, FileRepositoryConnectorFactory.class);
        locator.addService(RepositoryConnectorFactory.class, WagonRepositoryConnectorFactory.class);
        locator.setServices(WagonProvider.class, new ManualWagonProvider());
    
        return locator.getService(RepositorySystem.class);
    }
    
    private static RepositorySystemSession getRepositorySystemSessionInstance(RepositorySystem system,
                                                                              LocalRepository localRepo)
    {
        MavenRepositorySystemSession session = new MavenRepositorySystemSession();
    
        session.setLocalRepositoryManager(system.newLocalRepositoryManager(localRepo));
    
        session.setTransferListener(new ConsoleTransferListener());
        session.setRepositoryListener(new ConsoleRepositoryListener());
    
        // Set this in order to generate dirty trees
        session.setDependencyGraphTransformer(null);
    
        return session;
    }
    
    0 讨论(0)
  • 2020-12-24 09:39

    I just whipped up a solution to both your and my problem:

    /*******************************************************************************
     * Copyright (c) 2013 TerraFrame, Inc. All rights reserved. 
     * 
     * This file is part of Runway SDK(tm).
     * 
     * Runway SDK(tm) is free software: you can redistribute it and/or modify
     * it under the terms of the GNU Lesser General Public License as
     * published by the Free Software Foundation, either version 3 of the
     * License, or (at your option) any later version.
     * 
     * Runway SDK(tm) is distributed in the hope that it will be useful, but
     * WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU Lesser General Public License for more details.
     * 
     * You should have received a copy of the GNU Lesser General Public
     * License along with Runway SDK(tm).  If not, see <http://www.gnu.org/licenses/>.
     ******************************************************************************/
    
    package com.test.mavenaether;
    
    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.List;
    
    import org.apache.maven.artifact.repository.ArtifactRepository;
    import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
    import org.apache.maven.artifact.repository.MavenArtifactRepository;
    import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
    import org.apache.maven.model.Model;
    import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
    import org.apache.maven.project.MavenProject;
    import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
    import org.sonatype.aether.artifact.Artifact;
    import org.sonatype.aether.resolution.DependencyResolutionException;
    import org.sonatype.aether.util.artifact.DefaultArtifact;
    import org.sonatype.aether.util.artifact.JavaScopes;
    
    import com.jcabi.aether.Aether;
    
    public class MavenAether
    {
      public static void main(String[] args) throws Exception
      {
        String classpath = getClasspathFromMavenProject(new File("/users/terraframe/documents/workspace/MavenSandbox/pom.xml"), new File("/users/terraframe/.m2/repository"));
        System.out.println("classpath = " + classpath);
      }
    
      public static String getClasspathFromMavenProject(File projectPom, File localRepoFolder) throws DependencyResolutionException, IOException, XmlPullParserException
      {
        MavenProject proj = loadProject(projectPom);
    
        proj.setRemoteArtifactRepositories(
            Arrays.asList(
                (ArtifactRepository) new MavenArtifactRepository(
                    "maven-central", "http://repo1.maven.org/maven2/", new DefaultRepositoryLayout(),
                    new ArtifactRepositoryPolicy(), new ArtifactRepositoryPolicy()
                )
            )
        );
    
        String classpath = "";
        Aether aether = new Aether(proj, localRepoFolder);
    
        List<org.apache.maven.model.Dependency> dependencies = proj.getDependencies();
        Iterator<org.apache.maven.model.Dependency> it = dependencies.iterator();
    
        while (it.hasNext()) {
          org.apache.maven.model.Dependency depend = it.next();
    
          final Collection<Artifact> deps = aether.resolve(
            new DefaultArtifact(depend.getGroupId(), depend.getArtifactId(), depend.getClassifier(), depend.getType(), depend.getVersion()),
            JavaScopes.RUNTIME
          );
    
          Iterator<Artifact> artIt = deps.iterator();
          while (artIt.hasNext()) {
            Artifact art = artIt.next();
            classpath = classpath + " " + art.getFile().getAbsolutePath();
          }
        }
    
        return classpath;
      }
    
      public static MavenProject loadProject(File pomFile) throws IOException, XmlPullParserException
      {
          MavenProject ret = null;
          MavenXpp3Reader mavenReader = new MavenXpp3Reader();
    
          if (pomFile != null && pomFile.exists())
          {
              FileReader reader = null;
    
              try
                  {
                  reader = new FileReader(pomFile);
                  Model model = mavenReader.read(reader);
                  model.setPomFile(pomFile);
    
                  ret = new MavenProject(model);
              }
              finally
              {
                reader.close();
              }
          }
    
          return ret;
      }
    }
    

    pom.xml:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.test</groupId>
      <artifactId>MavenSandbox</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    
      <dependencies>
        <dependency>
          <groupId>com.jcabi</groupId>
          <artifactId>jcabi-aether</artifactId>
          <version>0.7.19</version>
        </dependency>
        <dependency>
          <groupId>org.apache.maven</groupId>
          <artifactId>maven-core</artifactId>
          <version>3.0.3</version>
        </dependency>
      </dependencies>
    </project>
    

    The code first loads the Maven project (using your function provided in the original question), then uses jcabi-aether to find the artifact in your local repository. You will need to change the two parameters in the main function: the location for the pom.xml of your project, and the location of your local repository.

    Enjoy! :)

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