Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load Maven Artifact via Classloader

Is it possible to load remote artifacts via Maven during runtime, e.g. using a specific (Maven) ClassLoader?

For my use case, a legacy software is using an URLClassLoader to pull a JAR containing some resources files during start-up of a test framework.

Problem is that we currently just use a fixed URL pointing to the repository and not actually using Maven artifact resolution at all.

Adding this to the projects dependency is no option because we want to refer to a specific version from an external configuration file (to run the test framework with different versions of our packaged use cases without changing code).

I hope you get what I want to achieve - it doesn't have to be the prettiest solution because we currently rely on a fixed URL pattern, I'd like to be dependent from the local maven setup instead.

like image 646
DoNuT Avatar asked Jan 29 '26 05:01

DoNuT


1 Answers

You may use Eclipse Aether (http://www.eclipse.org/aether) to resolve and download the JAR artifacts from maven repositories using GAV coordinates.

Then use a regular URLClassLoader with the JAR you've downloaded.

You can find some examples there: https://github.com/eclipse/aether-demo/blob/master/aether-demo-snippets/

But basically, what you should do is the following:

    DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
    locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
    locator.addService(TransporterFactory.class, FileTransporterFactory.class);
    locator.addService(TransporterFactory.class, HttpTransporterFactory.class);

    RepositorySystem system = locator.getService(RepositorySystem.class);

    DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();

    LocalRepository localRepo = new LocalRepository("/path/to/your/local/repo");
    session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));

    // Set the coordinates of the artifact to download
    Artifact artifact = new DefaultArtifact("<groupId>", "<artifactId>", "jar", "<version>");
    ArtifactRequest artifactRequest = new ArtifactRequest();
    artifactRequest.setArtifact(artifact);

    // Search in central repo
    artifactRequest.addRepository(new RemoteRepository.Builder("central", "default", "http://repo1.maven.org/maven2/").build());

    // Also search in your custom repo
    artifactRequest.addRepository(new RemoteRepository.Builder("your-repository", "default", "http://your.repository.url/").build());

    // Actually resolve (and download if necessary) the artifact
    ArtifactResult artifactResult = system.resolveArtifact(session, artifactRequest);

    artifact = artifactResult.getArtifact();

    // Create a classloader with the downloaded artifact.
    ClassLoader classLoader = new URLClassLoader(new URL[] { artifact.getFile().toURI().toURL() });
like image 192
Benjamin Avatar answered Jan 30 '26 23:01

Benjamin