mirror of https://github.com/apache/maven.git
MNG-5771 user-defined core extensions
read ${maven.projectBasedir}/.mvn/extensions.xml and create core extensions realms during maven runtime bootstrap. this required short-lived bootstrap plexus container to resolve extensions. individual extensions realms are wired to maven.ext realm according to META-INF/maven/extension.xml exported packages specification Signed-off-by: Igor Fedorenko <ifedorenko@apache.org>
This commit is contained in:
parent
e2a0792840
commit
6efacdb3fc
|
@ -29,9 +29,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
|
||||
import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter;
|
||||
import org.apache.maven.extension.internal.DefaultCoreExports;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.apache.maven.extension.internal.CoreExportsProvider;
|
||||
|
||||
/**
|
||||
* @author Jason van Zyl
|
||||
|
@ -46,16 +44,24 @@ public class DefaultArtifactFilterManager
|
|||
// this is a live injected collection
|
||||
protected final List<ArtifactFilterManagerDelegate> delegates;
|
||||
|
||||
protected final Set<String> coreArtifacts;
|
||||
protected Set<String> excludedArtifacts;
|
||||
|
||||
protected final Set<String> excludedArtifacts;
|
||||
private final Set<String> coreArtifacts;
|
||||
|
||||
@Inject
|
||||
public DefaultArtifactFilterManager( List<ArtifactFilterManagerDelegate> delegates, DefaultCoreExports extensions )
|
||||
public DefaultArtifactFilterManager( List<ArtifactFilterManagerDelegate> delegates, CoreExportsProvider coreExports )
|
||||
{
|
||||
this.delegates = delegates;
|
||||
this.coreArtifacts = ImmutableSet.copyOf( extensions.getExportedArtifacts() );
|
||||
this.excludedArtifacts = new LinkedHashSet<String>( extensions.getExportedArtifacts() );
|
||||
this.coreArtifacts = coreExports.get().getExportedArtifacts();
|
||||
}
|
||||
|
||||
private synchronized Set<String> getExcludedArtifacts()
|
||||
{
|
||||
if ( excludedArtifacts == null )
|
||||
{
|
||||
excludedArtifacts = new LinkedHashSet<String>( coreArtifacts );
|
||||
}
|
||||
return excludedArtifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,7 +71,7 @@ public class DefaultArtifactFilterManager
|
|||
*/
|
||||
public ArtifactFilter getArtifactFilter()
|
||||
{
|
||||
Set<String> excludes = new LinkedHashSet<String>( excludedArtifacts );
|
||||
Set<String> excludes = new LinkedHashSet<String>( getExcludedArtifacts() );
|
||||
|
||||
for ( ArtifactFilterManagerDelegate delegate : delegates )
|
||||
{
|
||||
|
@ -87,7 +93,7 @@ public class DefaultArtifactFilterManager
|
|||
|
||||
public void excludeArtifact( String artifactId )
|
||||
{
|
||||
excludedArtifacts.add( artifactId );
|
||||
getExcludedArtifacts().add( artifactId );
|
||||
}
|
||||
|
||||
public Set<String> getCoreArtifactExcludes()
|
||||
|
|
|
@ -23,7 +23,6 @@ import java.io.File;
|
|||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -37,7 +36,7 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.apache.maven.artifact.ArtifactUtils;
|
||||
import org.apache.maven.classrealm.ClassRealmRequest.RealmType;
|
||||
import org.apache.maven.extension.internal.DefaultCoreExports;
|
||||
import org.apache.maven.extension.internal.CoreExportsProvider;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.codehaus.plexus.MutablePlexusContainer;
|
||||
|
@ -49,8 +48,6 @@ import org.codehaus.plexus.logging.Logger;
|
|||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* Manages the class realms used by Maven. <strong>Warning:</strong> This is an internal utility class that is only
|
||||
* public for technical reasons, it is not part of the public API. In particular, this class can be changed or deleted
|
||||
|
@ -63,6 +60,7 @@ import com.google.common.collect.ImmutableMap;
|
|||
public class DefaultClassRealmManager
|
||||
implements ClassRealmManager
|
||||
{
|
||||
public static final String API_REALMID = "maven.api";
|
||||
|
||||
/**
|
||||
* During normal command line build, ClassWorld is loaded by jvm system classloader, which only includes
|
||||
|
@ -83,25 +81,22 @@ public class DefaultClassRealmManager
|
|||
// this is a live injected collection
|
||||
private final List<ClassRealmManagerDelegate> delegates;
|
||||
|
||||
private final Map<String, ClassLoader> coreImports;
|
||||
|
||||
private ClassRealm mavenRealm;
|
||||
private final ClassRealm mavenApiRealm;
|
||||
|
||||
@Inject
|
||||
public DefaultClassRealmManager( Logger logger, PlexusContainer container,
|
||||
List<ClassRealmManagerDelegate> delegates, DefaultCoreExports coreExtensions )
|
||||
List<ClassRealmManagerDelegate> delegates, CoreExportsProvider exports )
|
||||
{
|
||||
this.logger = logger;
|
||||
this.world = ( (MutablePlexusContainer) container ).getClassWorld();
|
||||
this.containerRealm = container.getContainerRealm();
|
||||
this.delegates = delegates;
|
||||
|
||||
Map<String, ClassLoader> coreImports = new HashMap<String, ClassLoader>();
|
||||
for ( String corePackage : coreExtensions.getExportedPackages() )
|
||||
{
|
||||
coreImports.put( corePackage, containerRealm );
|
||||
}
|
||||
this.coreImports = ImmutableMap.copyOf( coreImports );
|
||||
Map<String, ClassLoader> foreignImports = exports.get().getExportedPackages();
|
||||
|
||||
this.mavenApiRealm =
|
||||
createRealm( API_REALMID, RealmType.Core, null /* parent */, null /* parentImports */,
|
||||
foreignImports, null /* artifacts */ );
|
||||
}
|
||||
|
||||
private ClassRealm newRealm( String id )
|
||||
|
@ -133,27 +128,9 @@ public class DefaultClassRealmManager
|
|||
}
|
||||
}
|
||||
|
||||
public synchronized ClassRealm getMavenApiRealm()
|
||||
public ClassRealm getMavenApiRealm()
|
||||
{
|
||||
if ( mavenRealm == null )
|
||||
{
|
||||
mavenRealm = newRealm( "maven.api" );
|
||||
|
||||
List<ClassRealmConstituent> constituents = new ArrayList<ClassRealmConstituent>();
|
||||
|
||||
List<String> parentImports = new ArrayList<String>();
|
||||
|
||||
Map<String, ClassLoader> foreignImports = new HashMap<String, ClassLoader>( coreImports );
|
||||
|
||||
callDelegates( mavenRealm, RealmType.Core, mavenRealm.getParentClassLoader(), parentImports,
|
||||
foreignImports, constituents );
|
||||
|
||||
wireRealm( mavenRealm, parentImports, foreignImports );
|
||||
|
||||
populateRealm( mavenRealm, constituents );
|
||||
}
|
||||
|
||||
return mavenRealm;
|
||||
return mavenApiRealm;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package org.apache.maven.extension.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 java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Provides information about artifacts (identified by groupId:artifactId string key) and classpath elements exported by
|
||||
* Maven core itself and loaded Maven core extensions.
|
||||
*
|
||||
* @since 3.2.6
|
||||
*/
|
||||
public class CoreExports
|
||||
{
|
||||
private final Set<String> artifacts;
|
||||
|
||||
private final Map<String, ClassLoader> packages;
|
||||
|
||||
public CoreExports( CoreExtensionEntry entry )
|
||||
{
|
||||
this( entry.getClassRealm(), entry.getExportedArtifacts(), entry.getExportedPackages() );
|
||||
}
|
||||
|
||||
public CoreExports( ClassRealm realm, Set<String> exportedArtifacts, Set<String> exportedPackages )
|
||||
{
|
||||
Map<String, ClassLoader> packages = new LinkedHashMap<String, ClassLoader>();
|
||||
for ( String pkg : exportedPackages )
|
||||
{
|
||||
packages.put( pkg, realm );
|
||||
}
|
||||
this.artifacts = ImmutableSet.copyOf( exportedArtifacts );
|
||||
this.packages = ImmutableMap.copyOf( packages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns artifacts exported by Maven core and core extensions. Artifacts are identified by their
|
||||
* groupId:artifactId string key.
|
||||
*/
|
||||
public Set<String> getExportedArtifacts()
|
||||
{
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns packages exported by Maven core and core extensions.
|
||||
*/
|
||||
public Map<String, ClassLoader> getExportedPackages()
|
||||
{
|
||||
return packages;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package org.apache.maven.extension.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 javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.codehaus.plexus.PlexusContainer;
|
||||
import org.eclipse.sisu.Nullable;
|
||||
|
||||
@Named
|
||||
@Singleton
|
||||
public class CoreExportsProvider
|
||||
{
|
||||
|
||||
private final CoreExports exports;
|
||||
|
||||
@Inject
|
||||
public CoreExportsProvider( PlexusContainer container, @Nullable CoreExports exports )
|
||||
{
|
||||
if ( exports == null )
|
||||
{
|
||||
this.exports = new CoreExports( CoreExtensionEntry.discoverFrom( container.getContainerRealm() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.exports = exports;
|
||||
}
|
||||
}
|
||||
|
||||
public CoreExports get()
|
||||
{
|
||||
return exports;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
package org.apache.maven.extension.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 java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.maven.project.ExtensionDescriptor;
|
||||
import org.apache.maven.project.ExtensionDescriptorBuilder;
|
||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||
import org.codehaus.plexus.util.IOUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* Provides information about artifacts (identified by groupId:artifactId string key) and classpath elements exported by
|
||||
* Maven core itself or a Maven core extension.
|
||||
*
|
||||
* @since 3.2.6
|
||||
*/
|
||||
public class CoreExtensionEntry
|
||||
{
|
||||
private final ClassRealm realm;
|
||||
|
||||
private final Set<String> artifacts;
|
||||
|
||||
private final Set<String> packages;
|
||||
|
||||
public CoreExtensionEntry( ClassRealm realm, Collection<String> artifacts, Collection<String> packages )
|
||||
{
|
||||
this.realm = realm;
|
||||
this.artifacts = ImmutableSet.copyOf( artifacts );
|
||||
this.packages = ImmutableSet.copyOf( packages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ClassLoader used to load extension classes.
|
||||
*/
|
||||
public ClassRealm getClassRealm()
|
||||
{
|
||||
return realm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns artifacts exported by the extension, identified by groupId:artifactId string key.
|
||||
*/
|
||||
public Set<String> getExportedArtifacts()
|
||||
{
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns classpath elements exported by the extension.
|
||||
*/
|
||||
public Set<String> getExportedPackages()
|
||||
{
|
||||
return packages;
|
||||
}
|
||||
|
||||
private static final ExtensionDescriptorBuilder builder = new ExtensionDescriptorBuilder();
|
||||
|
||||
public static CoreExtensionEntry discoverFrom( ClassRealm loader )
|
||||
{
|
||||
Set<String> artifacts = new LinkedHashSet<String>();
|
||||
Set<String> packages = new LinkedHashSet<String>();
|
||||
|
||||
try
|
||||
{
|
||||
Enumeration<URL> urls = loader.getResources( builder.getExtensionDescriptorLocation() );
|
||||
while ( urls.hasMoreElements() )
|
||||
{
|
||||
InputStream is = urls.nextElement().openStream();
|
||||
try
|
||||
{
|
||||
ExtensionDescriptor descriptor = builder.build( is );
|
||||
artifacts.addAll( descriptor.getExportedArtifacts() );
|
||||
packages.addAll( descriptor.getExportedPackages() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( is );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( IOException ignored )
|
||||
{
|
||||
// exports descriptors are entirely optional
|
||||
}
|
||||
|
||||
return new CoreExtensionEntry( loader, artifacts, packages );
|
||||
}
|
||||
|
||||
public static CoreExtensionEntry discoverFrom( ClassRealm loader, Collection<File> classpath )
|
||||
{
|
||||
Set<String> artifacts = new LinkedHashSet<String>();
|
||||
Set<String> packages = new LinkedHashSet<String>();
|
||||
|
||||
try
|
||||
{
|
||||
for ( File entry : classpath )
|
||||
{
|
||||
ExtensionDescriptor descriptor = builder.build( entry );
|
||||
if ( descriptor != null )
|
||||
{
|
||||
artifacts.addAll( descriptor.getExportedArtifacts() );
|
||||
packages.addAll( descriptor.getExportedPackages() );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( IOException ignored )
|
||||
{
|
||||
// exports descriptors are entirely optional
|
||||
}
|
||||
|
||||
return new CoreExtensionEntry( loader, artifacts, packages );
|
||||
}
|
||||
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package org.apache.maven.extension.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 java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.maven.project.ExtensionDescriptor;
|
||||
import org.apache.maven.project.ExtensionDescriptorBuilder;
|
||||
import org.codehaus.plexus.PlexusContainer;
|
||||
import org.codehaus.plexus.util.IOUtil;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @since 3.2.6
|
||||
*/
|
||||
@Named
|
||||
@Singleton
|
||||
public class DefaultCoreExports
|
||||
{
|
||||
private static final ExtensionDescriptorBuilder builder = new ExtensionDescriptorBuilder();
|
||||
|
||||
private final Set<String> artifacts;
|
||||
|
||||
private final Set<String> packages;
|
||||
|
||||
@Inject
|
||||
public DefaultCoreExports( PlexusContainer container )
|
||||
throws IOException
|
||||
{
|
||||
Set<String> artifacts = new LinkedHashSet<String>();
|
||||
Set<String> packages = new LinkedHashSet<String>();
|
||||
|
||||
Enumeration<URL> extensions =
|
||||
container.getContainerRealm().getResources( builder.getExtensionDescriptorLocation() );
|
||||
while ( extensions.hasMoreElements() )
|
||||
{
|
||||
InputStream is = extensions.nextElement().openStream();
|
||||
try
|
||||
{
|
||||
ExtensionDescriptor descriptor = builder.build( is );
|
||||
|
||||
artifacts.addAll( descriptor.getExportedArtifacts() );
|
||||
packages.addAll( descriptor.getExportedPackages() );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( is );
|
||||
}
|
||||
}
|
||||
this.artifacts = ImmutableSet.copyOf( artifacts );
|
||||
this.packages = ImmutableSet.copyOf( packages );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns artifacts exported by Maven core and core extensions. Artifacts are identified by their
|
||||
* groupId:artifactId.
|
||||
*/
|
||||
public Set<String> getExportedArtifacts()
|
||||
{
|
||||
return artifacts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns packages exported by Maven core and core extensions.
|
||||
*/
|
||||
public Set<String> getExportedPackages()
|
||||
{
|
||||
return packages;
|
||||
}
|
||||
}
|
|
@ -136,9 +136,31 @@ public class DefaultPluginDependenciesResolver
|
|||
return pluginArtifact;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.2.6
|
||||
*/
|
||||
public DependencyNode resolveCoreExtension( Plugin plugin, DependencyFilter dependencyFilter,
|
||||
List<RemoteRepository> repositories, RepositorySystemSession session )
|
||||
throws PluginResolutionException
|
||||
{
|
||||
return resolveInternal( plugin, null /* pluginArtifact */, dependencyFilter, null /* transformer */,
|
||||
repositories, session );
|
||||
}
|
||||
|
||||
public DependencyNode resolve( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
|
||||
List<RemoteRepository> repositories, RepositorySystemSession session )
|
||||
throws PluginResolutionException
|
||||
{
|
||||
DependencyFilter resolutionFilter =
|
||||
new ExclusionsDependencyFilter( artifactFilterManager.getCoreArtifactExcludes() );
|
||||
resolutionFilter = AndDependencyFilter.newInstance( resolutionFilter, dependencyFilter );
|
||||
return resolveInternal( plugin, pluginArtifact, resolutionFilter, new PlexusUtilsInjector(), repositories, session );
|
||||
}
|
||||
|
||||
private DependencyNode resolveInternal( Plugin plugin, Artifact pluginArtifact, DependencyFilter dependencyFilter,
|
||||
DependencyGraphTransformer transformer,
|
||||
List<RemoteRepository> repositories, RepositorySystemSession session )
|
||||
throws PluginResolutionException
|
||||
{
|
||||
RequestTrace trace = RequestTrace.newChild( null, plugin );
|
||||
|
||||
|
@ -148,11 +170,7 @@ public class DefaultPluginDependenciesResolver
|
|||
}
|
||||
|
||||
DependencyFilter collectionFilter = new ScopeDependencyFilter( "provided", "test" );
|
||||
|
||||
DependencyFilter resolutionFilter =
|
||||
new ExclusionsDependencyFilter( artifactFilterManager.getCoreArtifactExcludes() );
|
||||
resolutionFilter = AndDependencyFilter.newInstance( resolutionFilter, dependencyFilter );
|
||||
resolutionFilter = new AndDependencyFilter( collectionFilter, resolutionFilter );
|
||||
DependencyFilter resolutionFilter = AndDependencyFilter.newInstance( collectionFilter, dependencyFilter );
|
||||
|
||||
DependencyNode node;
|
||||
|
||||
|
@ -161,9 +179,8 @@ public class DefaultPluginDependenciesResolver
|
|||
DependencySelector selector =
|
||||
AndDependencySelector.newInstance( session.getDependencySelector(), new WagonExcluder() );
|
||||
|
||||
DependencyGraphTransformer transformer =
|
||||
ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(),
|
||||
new PlexusUtilsInjector() );
|
||||
transformer =
|
||||
ChainedDependencyGraphTransformer.newInstance( session.getDependencyGraphTransformer(), transformer );
|
||||
|
||||
DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession( session );
|
||||
pluginSession.setDependencySelector( selector );
|
||||
|
|
|
@ -121,10 +121,24 @@
|
|||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.eclipse.sisu</groupId>
|
||||
<artifactId>sisu-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-component-metadata</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.modello</groupId>
|
||||
<artifactId>modello-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<version>1.0.0</version>
|
||||
<models>
|
||||
<model>src/main/mdo/core-extensions.mdo</model>
|
||||
</models>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
|
@ -19,11 +19,14 @@ package org.apache.maven.cli;
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.Console;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -47,6 +50,9 @@ import org.apache.maven.building.Problem;
|
|||
import org.apache.maven.building.Source;
|
||||
import org.apache.maven.cli.event.DefaultEventSpyContext;
|
||||
import org.apache.maven.cli.event.ExecutionEventLogger;
|
||||
import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
|
||||
import org.apache.maven.cli.internal.extension.model.CoreExtension;
|
||||
import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
|
||||
import org.apache.maven.cli.logging.Slf4jConfiguration;
|
||||
import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
|
||||
import org.apache.maven.cli.logging.Slf4jLoggerManager;
|
||||
|
@ -64,6 +70,8 @@ import org.apache.maven.execution.MavenExecutionRequest;
|
|||
import org.apache.maven.execution.MavenExecutionRequestPopulationException;
|
||||
import org.apache.maven.execution.MavenExecutionRequestPopulator;
|
||||
import org.apache.maven.execution.MavenExecutionResult;
|
||||
import org.apache.maven.extension.internal.CoreExports;
|
||||
import org.apache.maven.extension.internal.CoreExtensionEntry;
|
||||
import org.apache.maven.lifecycle.LifecycleExecutionException;
|
||||
import org.apache.maven.model.building.ModelProcessor;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
@ -87,7 +95,9 @@ import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
|||
import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
|
||||
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
|
||||
import org.codehaus.plexus.logging.LoggerManager;
|
||||
import org.codehaus.plexus.util.IOUtil;
|
||||
import org.codehaus.plexus.util.StringUtils;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
import org.eclipse.aether.transfer.TransferListener;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -134,6 +144,8 @@ public class MavenCli
|
|||
|
||||
private static final String EXT_CLASS_PATH = "maven.ext.class.path";
|
||||
|
||||
private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";
|
||||
|
||||
private ClassWorld classWorld;
|
||||
|
||||
private LoggerManager plexusLoggerManager;
|
||||
|
@ -485,21 +497,44 @@ public class MavenCli
|
|||
cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
|
||||
}
|
||||
|
||||
DefaultPlexusContainer container;
|
||||
ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
|
||||
if ( coreRealm == null )
|
||||
{
|
||||
coreRealm = cliRequest.classWorld.getRealms().iterator().next();
|
||||
}
|
||||
|
||||
List<File> extClassPath = parseExtClasspath( cliRequest );
|
||||
|
||||
CoreExtensionEntry coreEntry = CoreExtensionEntry.discoverFrom( coreRealm );
|
||||
List<CoreExtensionEntry> extensions =
|
||||
loadCoreExtensions( cliRequest, coreRealm, coreEntry.getExportedArtifacts() );
|
||||
|
||||
ClassRealm containerRealm = setupContainerRealm( cliRequest.classWorld, coreRealm, extClassPath, extensions );
|
||||
|
||||
ContainerConfiguration cc = new DefaultContainerConfiguration()
|
||||
.setClassWorld( cliRequest.classWorld )
|
||||
.setRealm( setupContainerRealm( cliRequest ) )
|
||||
.setRealm( containerRealm )
|
||||
.setClassPathScanning( PlexusConstants.SCANNING_INDEX )
|
||||
.setAutoWiring( true )
|
||||
.setName( "maven" );
|
||||
|
||||
container = new DefaultPlexusContainer( cc, new AbstractModule()
|
||||
Set<String> exportedArtifacts = new HashSet<String>( coreEntry.getExportedArtifacts() );
|
||||
Set<String> exportedPackages = new HashSet<String>( coreEntry.getExportedPackages() );
|
||||
for ( CoreExtensionEntry extension : extensions )
|
||||
{
|
||||
exportedArtifacts.addAll( extension.getExportedArtifacts() );
|
||||
exportedPackages.addAll( extension.getExportedPackages() );
|
||||
}
|
||||
|
||||
final CoreExports exports = new CoreExports( containerRealm, exportedArtifacts, exportedPackages );
|
||||
|
||||
DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
|
||||
{
|
||||
@Override
|
||||
protected void configure()
|
||||
{
|
||||
bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
|
||||
bind( CoreExports.class ).toInstance( exports );
|
||||
}
|
||||
} );
|
||||
|
||||
|
@ -508,6 +543,11 @@ public class MavenCli
|
|||
|
||||
container.setLoggerManager( plexusLoggerManager );
|
||||
|
||||
for ( CoreExtensionEntry extension : extensions )
|
||||
{
|
||||
container.discoverComponents( extension.getClassRealm() );
|
||||
}
|
||||
|
||||
customizeContainer( container );
|
||||
|
||||
container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
|
||||
|
@ -543,49 +583,170 @@ public class MavenCli
|
|||
return container;
|
||||
}
|
||||
|
||||
private ClassRealm setupContainerRealm( CliRequest cliRequest )
|
||||
private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
|
||||
Set<String> providedArtifacts )
|
||||
{
|
||||
if ( cliRequest.projectBaseDirectory == null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
File extensionsFile = new File( cliRequest.projectBaseDirectory, EXTENSIONS_FILENAME );
|
||||
if ( !extensionsFile.isFile() )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
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 ) //
|
||||
.setName( "maven" );
|
||||
|
||||
DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
|
||||
{
|
||||
@Override
|
||||
protected void configure()
|
||||
{
|
||||
bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
|
||||
}
|
||||
} );
|
||||
|
||||
try
|
||||
{
|
||||
container.setLookupRealm( null );
|
||||
|
||||
container.setLoggerManager( plexusLoggerManager );
|
||||
|
||||
container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
|
||||
|
||||
Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
|
||||
|
||||
executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
|
||||
settingsBuilder = container.lookup( SettingsBuilder.class );
|
||||
|
||||
MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );
|
||||
settings( cliRequest, request );
|
||||
request = populateRequest( cliRequest, request );
|
||||
request = executionRequestPopulator.populateDefaults( request );
|
||||
|
||||
BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
|
||||
return resolver.loadCoreExtensions( request, providedArtifacts, extensions );
|
||||
}
|
||||
finally
|
||||
{
|
||||
executionRequestPopulator = null;
|
||||
settingsBuilder = null;
|
||||
container.dispose();
|
||||
}
|
||||
}
|
||||
catch ( RuntimeException e )
|
||||
{
|
||||
// runtime exceptions are most likely bugs in maven, let them bubble up to the user
|
||||
throw e;
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
slf4jLogger.warn( "Failed to read extensions descriptor " + extensionsFile + ": " + e.getMessage() );
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )
|
||||
throws IOException, XmlPullParserException
|
||||
{
|
||||
CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader();
|
||||
InputStream is = null;
|
||||
try
|
||||
{
|
||||
is = new BufferedInputStream( new FileInputStream( extensionsFile ) );
|
||||
return parser.read( is ).getExtensions();
|
||||
}
|
||||
finally
|
||||
{
|
||||
IOUtil.close( is );
|
||||
}
|
||||
}
|
||||
|
||||
private ClassRealm setupContainerRealm( ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath,
|
||||
List<CoreExtensionEntry> extensions )
|
||||
throws Exception
|
||||
{
|
||||
ClassRealm containerRealm = null;
|
||||
if ( !extClassPath.isEmpty() || !extensions.isEmpty() )
|
||||
{
|
||||
ClassRealm extRealm = classWorld.newRealm( "maven.ext", null );
|
||||
|
||||
extRealm.setParentRealm( coreRealm );
|
||||
|
||||
slf4jLogger.debug( "Populating class realm " + extRealm.getId() );
|
||||
|
||||
for ( File file : extClassPath )
|
||||
{
|
||||
slf4jLogger.debug( " Included " + file );
|
||||
|
||||
extRealm.addURL( file.toURI().toURL() );
|
||||
}
|
||||
|
||||
for ( CoreExtensionEntry entry : reverse( extensions ) )
|
||||
{
|
||||
Set<String> exportedPackages = entry.getExportedPackages();
|
||||
ClassRealm realm = entry.getClassRealm();
|
||||
for ( String exportedPackage : exportedPackages )
|
||||
{
|
||||
extRealm.importFrom( realm, exportedPackage );
|
||||
}
|
||||
if ( exportedPackages.isEmpty() )
|
||||
{
|
||||
// sisu uses realm imports to establish component visibility
|
||||
extRealm.importFrom( realm, realm.getId() );
|
||||
}
|
||||
}
|
||||
|
||||
return extRealm;
|
||||
}
|
||||
|
||||
return coreRealm;
|
||||
}
|
||||
|
||||
private static <T> List<T> reverse( List<T> list )
|
||||
{
|
||||
List<T> copy = new ArrayList<T>( list );
|
||||
Collections.reverse( copy );
|
||||
return copy;
|
||||
}
|
||||
|
||||
private List<File> parseExtClasspath( CliRequest cliRequest )
|
||||
{
|
||||
String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
|
||||
if ( extClassPath == null )
|
||||
{
|
||||
extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
|
||||
}
|
||||
|
||||
List<File> jars = new ArrayList<File>();
|
||||
|
||||
if ( StringUtils.isNotEmpty( extClassPath ) )
|
||||
{
|
||||
String[] jars = StringUtils.split( extClassPath, File.pathSeparator );
|
||||
|
||||
if ( jars.length > 0 )
|
||||
for ( String jar : StringUtils.split( extClassPath, File.pathSeparator ) )
|
||||
{
|
||||
ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
|
||||
if ( coreRealm == null )
|
||||
{
|
||||
coreRealm = cliRequest.classWorld.getRealms().iterator().next();
|
||||
}
|
||||
File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
|
||||
|
||||
ClassRealm extRealm = cliRequest.classWorld.newRealm( "maven.ext", null );
|
||||
slf4jLogger.debug( " Included " + file );
|
||||
|
||||
slf4jLogger.debug( "Populating class realm " + extRealm.getId() );
|
||||
|
||||
for ( String jar : jars )
|
||||
{
|
||||
File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
|
||||
|
||||
slf4jLogger.debug( " Included " + file );
|
||||
|
||||
extRealm.addURL( file.toURI().toURL() );
|
||||
}
|
||||
|
||||
extRealm.setParentRealm( coreRealm );
|
||||
|
||||
containerRealm = extRealm;
|
||||
jars.add( file );
|
||||
}
|
||||
}
|
||||
|
||||
return containerRealm;
|
||||
return jars;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -813,6 +974,12 @@ public class MavenCli
|
|||
@SuppressWarnings( "checkstyle:methodlength" )
|
||||
private void settings( CliRequest cliRequest )
|
||||
throws Exception
|
||||
{
|
||||
settings( cliRequest, cliRequest.request );
|
||||
}
|
||||
|
||||
private void settings( CliRequest cliRequest, MavenExecutionRequest request )
|
||||
throws Exception
|
||||
{
|
||||
File userSettingsFile;
|
||||
|
||||
|
@ -851,8 +1018,8 @@ public class MavenCli
|
|||
globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
|
||||
}
|
||||
|
||||
cliRequest.request.setGlobalSettingsFile( globalSettingsFile );
|
||||
cliRequest.request.setUserSettingsFile( userSettingsFile );
|
||||
request.setGlobalSettingsFile( globalSettingsFile );
|
||||
request.setUserSettingsFile( userSettingsFile );
|
||||
|
||||
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
|
||||
settingsRequest.setGlobalSettingsFile( globalSettingsFile );
|
||||
|
@ -860,7 +1027,10 @@ public class MavenCli
|
|||
settingsRequest.setSystemProperties( cliRequest.systemProperties );
|
||||
settingsRequest.setUserProperties( cliRequest.userProperties );
|
||||
|
||||
eventSpyDispatcher.onEvent( settingsRequest );
|
||||
if ( eventSpyDispatcher != null )
|
||||
{
|
||||
eventSpyDispatcher.onEvent( settingsRequest );
|
||||
}
|
||||
|
||||
slf4jLogger.debug( "Reading global settings from "
|
||||
+ getLocation( settingsRequest.getGlobalSettingsSource(),
|
||||
|
@ -870,9 +1040,12 @@ public class MavenCli
|
|||
|
||||
SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
|
||||
|
||||
eventSpyDispatcher.onEvent( settingsResult );
|
||||
if ( eventSpyDispatcher != null )
|
||||
{
|
||||
eventSpyDispatcher.onEvent( settingsResult );
|
||||
}
|
||||
|
||||
executionRequestPopulator.populateFromSettings( cliRequest.request, settingsResult.getEffectiveSettings() );
|
||||
executionRequestPopulator.populateFromSettings( request, settingsResult.getEffectiveSettings() );
|
||||
|
||||
if ( !settingsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
|
||||
{
|
||||
|
@ -982,7 +1155,11 @@ public class MavenCli
|
|||
|
||||
private MavenExecutionRequest populateRequest( CliRequest cliRequest )
|
||||
{
|
||||
MavenExecutionRequest request = cliRequest.request;
|
||||
return populateRequest( cliRequest, cliRequest.request );
|
||||
}
|
||||
|
||||
private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecutionRequest request )
|
||||
{
|
||||
CommandLine commandLine = cliRequest.commandLine;
|
||||
String workingDirectory = cliRequest.workingDirectory;
|
||||
boolean quiet = cliRequest.quiet;
|
||||
|
@ -1127,7 +1304,10 @@ public class MavenCli
|
|||
}
|
||||
|
||||
ExecutionListener executionListener = new ExecutionEventLogger();
|
||||
executionListener = eventSpyDispatcher.chainListener( executionListener );
|
||||
if ( eventSpyDispatcher != null )
|
||||
{
|
||||
executionListener = eventSpyDispatcher.chainListener( executionListener );
|
||||
}
|
||||
|
||||
String alternatePomFile = null;
|
||||
if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
|
||||
|
@ -1172,7 +1352,7 @@ public class MavenCli
|
|||
|
||||
request.setPom( pom );
|
||||
}
|
||||
else
|
||||
else if ( modelProcessor != null )
|
||||
{
|
||||
File pom = modelProcessor.locatePom( baseDirectory );
|
||||
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
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 java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.apache.maven.RepositoryUtils;
|
||||
import org.apache.maven.cli.internal.extension.model.CoreExtension;
|
||||
import org.apache.maven.execution.MavenExecutionRequest;
|
||||
import org.apache.maven.extension.internal.CoreExtensionEntry;
|
||||
import org.apache.maven.internal.aether.DefaultRepositorySystemSessionFactory;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.plugin.PluginResolutionException;
|
||||
import org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver;
|
||||
import org.codehaus.plexus.DefaultPlexusContainer;
|
||||
import org.codehaus.plexus.PlexusContainer;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||
import org.codehaus.plexus.logging.Logger;
|
||||
import org.eclipse.aether.RepositorySystemSession;
|
||||
import org.eclipse.aether.artifact.Artifact;
|
||||
import org.eclipse.aether.graph.DependencyFilter;
|
||||
import org.eclipse.aether.graph.DependencyNode;
|
||||
import org.eclipse.aether.repository.RemoteRepository;
|
||||
import org.eclipse.aether.util.filter.ExclusionsDependencyFilter;
|
||||
import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator;
|
||||
|
||||
@Named
|
||||
public class BootstrapCoreExtensionManager
|
||||
{
|
||||
private final Logger log;
|
||||
|
||||
private final DefaultPluginDependenciesResolver pluginDependenciesResolver;
|
||||
|
||||
private final DefaultRepositorySystemSessionFactory repositorySystemSessionFactory;
|
||||
|
||||
private final ClassWorld classWorld;
|
||||
|
||||
private final ClassRealm parentRealm;
|
||||
|
||||
@Inject
|
||||
public BootstrapCoreExtensionManager( Logger log, DefaultPluginDependenciesResolver pluginDependenciesResolver,
|
||||
DefaultRepositorySystemSessionFactory repositorySystemSessionFactory,
|
||||
PlexusContainer container )
|
||||
{
|
||||
this.log = log;
|
||||
this.pluginDependenciesResolver = pluginDependenciesResolver;
|
||||
this.repositorySystemSessionFactory = repositorySystemSessionFactory;
|
||||
this.classWorld = ( (DefaultPlexusContainer) container ).getClassWorld();
|
||||
this.parentRealm = container.getContainerRealm();
|
||||
}
|
||||
|
||||
public List<CoreExtensionEntry> loadCoreExtensions( MavenExecutionRequest request, Set<String> providedArtifacts,
|
||||
List<CoreExtension> extensions )
|
||||
throws Exception
|
||||
{
|
||||
RepositorySystemSession repoSession = repositorySystemSessionFactory.newRepositorySession( request );
|
||||
List<RemoteRepository> repositories = RepositoryUtils.toRepos( request.getPluginArtifactRepositories() );
|
||||
|
||||
return resolveCoreExtensions( repoSession, repositories, providedArtifacts, extensions );
|
||||
}
|
||||
|
||||
private List<CoreExtensionEntry> resolveCoreExtensions( RepositorySystemSession repoSession,
|
||||
List<RemoteRepository> repositories,
|
||||
Set<String> providedArtifacts,
|
||||
List<CoreExtension> configuration )
|
||||
throws Exception
|
||||
{
|
||||
List<CoreExtensionEntry> extensions = new ArrayList<CoreExtensionEntry>();
|
||||
|
||||
DependencyFilter dependencyFilter = new ExclusionsDependencyFilter( providedArtifacts );
|
||||
|
||||
for ( CoreExtension extension : configuration )
|
||||
{
|
||||
List<Artifact> artifacts = resolveExtension( extension, repoSession, repositories, dependencyFilter );
|
||||
if ( !artifacts.isEmpty() )
|
||||
{
|
||||
extensions.add( createExtension( extension, artifacts ) );
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList( extensions );
|
||||
}
|
||||
|
||||
private CoreExtensionEntry createExtension( CoreExtension extension, List<Artifact> artifacts )
|
||||
throws Exception
|
||||
{
|
||||
String realmId =
|
||||
"coreExtension>" + extension.getGroupId() + ":" + extension.getArtifactId() + ":" + extension.getVersion();
|
||||
ClassRealm realm = classWorld.newRealm( realmId, null );
|
||||
log.debug( "Populating class realm " + realm.getId() );
|
||||
realm.setParentRealm( parentRealm );
|
||||
for ( Artifact artifact : artifacts )
|
||||
{
|
||||
File file = artifact.getFile();
|
||||
log.debug( " Included " + file );
|
||||
realm.addURL( file.toURI().toURL() );
|
||||
}
|
||||
return CoreExtensionEntry.discoverFrom( realm, Collections.singleton( artifacts.get( 0 ).getFile() ) );
|
||||
}
|
||||
|
||||
private List<Artifact> resolveExtension( CoreExtension extension, RepositorySystemSession repoSession,
|
||||
List<RemoteRepository> repositories, DependencyFilter dependencyFilter )
|
||||
throws PluginResolutionException
|
||||
{
|
||||
Plugin plugin = new Plugin();
|
||||
plugin.setGroupId( extension.getGroupId() );
|
||||
plugin.setArtifactId( extension.getArtifactId() );
|
||||
plugin.setVersion( extension.getVersion() );
|
||||
|
||||
DependencyNode root =
|
||||
pluginDependenciesResolver.resolveCoreExtension( plugin, dependencyFilter, repositories, repoSession );
|
||||
PreorderNodeListGenerator nlg = new PreorderNodeListGenerator();
|
||||
root.accept( nlg );
|
||||
List<Artifact> artifacts = nlg.getArtifacts( false );
|
||||
|
||||
return artifacts;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
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.
|
||||
|
||||
-->
|
||||
|
||||
<model xmlns="http://modello.codehaus.org/MODELLO/1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<id>CoreExtensions</id>
|
||||
<name>CoreExtensions</name>
|
||||
|
||||
<defaults>
|
||||
<default>
|
||||
<key>package</key>
|
||||
<value>org.apache.maven.cli.internal.extension.model</value>
|
||||
</default>
|
||||
</defaults>
|
||||
|
||||
<classes>
|
||||
<class rootElement="true" xml.tagName="extensions">
|
||||
<name>CoreExtensions</name>
|
||||
<version>1.0.0+</version>
|
||||
<fields>
|
||||
<field>
|
||||
<name>extensions</name>
|
||||
<version>1.0.0+</version>
|
||||
<association xml.itemsStyle="flat">
|
||||
<type>CoreExtension</type>
|
||||
<multiplicity>*</multiplicity>
|
||||
</association>
|
||||
</field>
|
||||
</fields>
|
||||
</class>
|
||||
<class xml.tagName="extension">
|
||||
<name>CoreExtension</name>
|
||||
<version>1.0.0+</version>
|
||||
<fields>
|
||||
<field>
|
||||
<name>groupId</name>
|
||||
<version>1.0.0+</version>
|
||||
<required>true</required>
|
||||
<type>String</type>
|
||||
</field>
|
||||
<field>
|
||||
<name>artifactId</name>
|
||||
<version>1.0.0+</version>
|
||||
<required>true</required>
|
||||
<type>String</type>
|
||||
</field>
|
||||
<field>
|
||||
<name>version</name>
|
||||
<version>1.0.0+</version>
|
||||
<required>true</required>
|
||||
<type>String</type>
|
||||
</field>
|
||||
</fields>
|
||||
</class>
|
||||
</classes>
|
||||
</model>
|
Loading…
Reference in New Issue