Incomplete injection of the plexus container when moving objects in a separate thread

I have the following simplified example involving a plexus container:

package de.vogel612.depanalyzer; import de.vogel612.depanalyzer.dependency.MavenResolutionTaskReal; import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.artifact.repository.layout.FlatRepositoryLayout; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; import org.codehaus.plexus.DefaultPlexusContainer; import org.codehaus.plexus.PlexusContainer; import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory; import org.eclipse.aether.impl.RemoteRepositoryManager; import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; import org.eclipse.aether.spi.connector.transport.TransporterFactory; import org.eclipse.aether.spi.locator.ServiceLocator; import org.eclipse.aether.transport.file.FileTransporterFactory; import org.eclipse.aether.transport.http.HttpTransporterFactory; public class MCVE { private static final ServiceLocator serviceLocator = MavenRepositorySystemUtils.newServiceLocator() .addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class) .addService(TransporterFactory.class, FileTransporterFactory.class) .addService(TransporterFactory.class, HttpTransporterFactory.class); private static final PriorityBlockingQueue<ResolutionTask> taskQueue = new PriorityBlockingQueue<>(); private static final ExecutorService consumer = Executors.newSingleThreadExector(); // actually initialized in main, since number of threads is configurable private static ExecutorService workers = Executors.newFixedThreadPool(threads, runnable -> { Thread result = new Thread(runnable, "WorkerQueue Thread"); result.setDaemon(true); return result; }); public static void main(String[] args) throws Exception { PlexusContainer container = new DefaultPlexusContainer(); // bind eclipse aether RepositorySystem container.addComponent(serviceLocator.getService(RepositorySystem.class), RepositorySystem.class, "default"); container.addComponent(serviceLocator.getService(RemoteRepositoryManager.class), RemoteRepositoryManager.class, "default"); container.addComponent(new DefaultRepositoryLayout(), ArtifactRepositoryLayout.class, "default"); container.addComponent(new FlatRepositoryLayout(), ArtifactRepositoryLayout.class, "flat"); taskQueue.put(container.lookup(MavenResolutionTask.class)); // ... } } 

Notice the last two lines of container.addComponent . Now, when I use the container in the following setup, I observed a very curious behavior:

 public class ResolutionTask extends CompletableFuture<List<SomeType>> implements Runnable { // actually contains an override for run, which does error handling } public class MavenResolutionTask extends ResolutionTask { @Requires Maven mavenInstance; @Override public void run() { // use the maven instance to compute some stuff: complete(Collections.singletonList()); } } 

This code works just fine and executes as intended:

 List<DependencyResult> results = new ArrayList<>(); while (!taskQueue.isEmpty()) { ResolutionTask currentTask = taskQueue.poll(); workers.execute(currentTask); results.addAll(currentTask.join()); } results.forEach(System.out::println); 

And as soon as this simplified work queue handler moves from the main thread as follows, I get an exception:

 consumer.execute(() -> { List<DependencyResult> results = new ArrayList<>(); while (!taskQueue.isEmpty()) { ResolutionTask currentTask = taskQueue.poll(); workers.execute(currentTask); results.addAll(currentTask.join()); } results.forEach(System.out::println); }); 

 Exception in thread "pool-1-thread-1" java.util.concurrent.CompletionException: java.lang.RuntimeException: Exception occurred during maven invocation at java.util.concurrent.CompletableFuture.reportJoin(CompletableFuture.java:375) at java.util.concurrent.CompletableFuture.join(CompletableFuture.java:1934) at de.vogel612.depanalyzer.Main.lambda$main$1(Main.java:109) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: java.lang.RuntimeException: Exception occurred during maven invocation at de.vogel612.depanalyzer.dependency.MavenResolutionTask.runImpl(MavenResolutionTask.java:35) at de.vogel612.depanalyzer.dependency.ResolutionTask.run(ResolutionTask.java:27) ... 3 more Suppressed: org.apache.maven.InternalErrorException: Internal error: java.lang.NullPointerException at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:164) at de.vogel612.depanalyzer.dependency.MavenResolutionTask.runImpl(MavenResolutionTask.java:32) ... 4 more Caused by: java.lang.NullPointerException at org.apache.maven.RepositoryUtils.getLayout(RepositoryUtils.java:217) at org.apache.maven.RepositoryUtils.toRepo(RepositoryUtils.java:201) at org.apache.maven.RepositoryUtils.toRepos(RepositoryUtils.java:191) at org.apache.maven.project.DefaultProjectBuilder$InternalConfig.<init>(DefaultProjectBuilder.java:684) at org.apache.maven.project.DefaultProjectBuilder.build(DefaultProjectBuilder.java:340) at org.apache.maven.DefaultMaven.collectProjects(DefaultMaven.java:637) at org.apache.maven.DefaultMaven.getProjectsForMavenReactor(DefaultMaven.java:586) at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:229) at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:152) ... 5 more 

The “root cause” of this exception indicates that it is not really useful. When maven tries to initialize the remote repository, it accesses Map<String, ArtifactRepositoryLayout> , which should contain the entries {"default", new DefaultRepositoryLayout()},{"flat", new FlatRepositoryLayout()} , but not

This map is located in the maven-compat LegacyRepositorySystem , but it was not correctly initialized when the taskQueue call was made to the consumer . <w> The code outputs the correct output when the consumer deduced from the equation ...

Why is this happening?

+5
source share

Source: https://habr.com/ru/post/1271400/


All Articles