[MNG-6326] Make the build fail if core extensions can not be loaded (#648)

This commit is contained in:
Guillaume Nodet 2022-01-07 09:51:21 +01:00
parent 2670c00751
commit b4773576a8
4 changed files with 134 additions and 62 deletions

View File

@ -743,6 +743,7 @@ public class MavenCli
private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm, private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
Set<String> providedArtifacts ) Set<String> providedArtifacts )
throws Exception
{ {
if ( cliRequest.multiModuleProjectDirectory == null ) if ( cliRequest.multiModuleProjectDirectory == null )
{ {
@ -755,75 +756,62 @@ public class MavenCli
return Collections.emptyList(); return Collections.emptyList();
} }
List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile );
if ( extensions.isEmpty() )
{
return Collections.emptyList();
}
ContainerConfiguration cc = new DefaultContainerConfiguration() //
.setClassWorld( cliRequest.classWorld ) //
.setRealm( containerRealm ) //
.setClassPathScanning( PlexusConstants.SCANNING_INDEX ) //
.setAutoWiring( true ) //
.setJSR250Lifecycle( true ) //
.setName( "maven" );
DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
{
@Override
protected void configure()
{
bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
}
} );
try try
{ {
List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile ); container.setLookupRealm( null );
if ( extensions.isEmpty() )
{
return Collections.emptyList();
}
ContainerConfiguration cc = new DefaultContainerConfiguration() // container.setLoggerManager( plexusLoggerManager );
.setClassWorld( cliRequest.classWorld ) //
.setRealm( containerRealm ) //
.setClassPathScanning( PlexusConstants.SCANNING_INDEX ) //
.setAutoWiring( true ) //
.setJSR250Lifecycle( true ) //
.setName( "maven" );
DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule() container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
{
@Override
protected void configure()
{
bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
}
} );
try Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
{
container.setLookupRealm( null );
container.setLoggerManager( plexusLoggerManager ); executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() ); configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
Thread.currentThread().setContextClassLoader( container.getContainerRealm() ); configure( cliRequest );
executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class ); MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );
configurationProcessors = container.lookupMap( ConfigurationProcessor.class ); populateRequest( cliRequest, request );
configure( cliRequest ); request = executionRequestPopulator.populateDefaults( request );
MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request ); BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
populateRequest( cliRequest, request ); return Collections.unmodifiableList( resolver.loadCoreExtensions( request, providedArtifacts,
extensions ) );
request = executionRequestPopulator.populateDefaults( request );
BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
return Collections.unmodifiableList( resolver.loadCoreExtensions( request, providedArtifacts,
extensions ) );
}
finally
{
executionRequestPopulator = null;
container.dispose();
}
} }
catch ( RuntimeException e ) finally
{ {
// runtime exceptions are most likely bugs in maven, let them bubble up to the user executionRequestPopulator = null;
throw e; container.dispose();
} }
catch ( Exception e )
{
slf4jLogger.warn( "Failed to read extensions descriptor from '{}'", extensionsFile, e );
}
return Collections.emptyList();
} }
private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile ) private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )

View File

@ -128,18 +128,29 @@ public class BootstrapCoreExtensionManager
private List<Artifact> resolveExtension( CoreExtension extension, RepositorySystemSession repoSession, private List<Artifact> resolveExtension( CoreExtension extension, RepositorySystemSession repoSession,
List<RemoteRepository> repositories, DependencyFilter dependencyFilter ) List<RemoteRepository> repositories, DependencyFilter dependencyFilter )
throws PluginResolutionException throws ExtensionResolutionException
{ {
Plugin plugin = new Plugin(); try
plugin.setGroupId( extension.getGroupId() ); {
plugin.setArtifactId( extension.getArtifactId() ); // TODO: enhance the PluginDependenciesResolver to provide a
plugin.setVersion( extension.getVersion() ); // TODO: resolveCoreExtension method which uses a CoreExtension
// TODO: object instead of a Plugin as this makes no sense
Plugin plugin = new Plugin();
plugin.setGroupId( extension.getGroupId() );
plugin.setArtifactId( extension.getArtifactId() );
plugin.setVersion( extension.getVersion() );
DependencyNode root = DependencyNode root = pluginDependenciesResolver
pluginDependenciesResolver.resolveCoreExtension( plugin, dependencyFilter, repositories, repoSession ); .resolveCoreExtension( plugin, dependencyFilter, repositories, repoSession );
PreorderNodeListGenerator nlg = new PreorderNodeListGenerator(); PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
root.accept( nlg ); root.accept( nlg );
return nlg.getArtifacts( false ); return nlg.getArtifacts( false );
}
catch ( PluginResolutionException e )
{
throw new ExtensionResolutionException( extension, e.getCause() );
}
} }
} }

View File

@ -0,0 +1,47 @@
package org.apache.maven.cli.internal;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.cli.internal.extension.model.CoreExtension;
/**
* Exception occurring trying to resolve a plugin.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
*/
public class ExtensionResolutionException
extends Exception
{
private final CoreExtension extension;
public ExtensionResolutionException( CoreExtension extension, Throwable cause )
{
super( "Extension " + extension.getId() + " or one of its dependencies could not be resolved: "
+ cause.getMessage(), cause );
this.extension = extension;
}
public CoreExtension getExtension()
{
return extension;
}
}

View File

@ -83,6 +83,32 @@
<type>String</type> <type>String</type>
</field> </field>
</fields> </fields>
<codeSegments>
<codeSegment>
<version>1.0.0+</version>
<code>
<![CDATA[
/**
* Gets the identifier of the extension.
*
* @return The extension id in the form {@code <groupId>:<artifactId>:<version>}, never {@code null}.
*/
public String getId()
{
StringBuilder id = new StringBuilder( 128 );
id.append( ( getGroupId() == null ) ? "[unknown-group-id]" : getGroupId() );
id.append( ":" );
id.append( ( getArtifactId() == null ) ? "[unknown-artifact-id]" : getArtifactId() );
id.append( ":" );
id.append( ( getVersion() == null ) ? "[unknown-version]" : getVersion() );
return id.toString();
}
]]>
</code>
</codeSegment>
</codeSegments>
</class> </class>
</classes> </classes>
</model> </model>