Resolving: MNG-767, MNG-768

o We should have a viable offline mode now. Plugin sensitivity updates to follow.

o See it0069 and it1014 for offline mode tests.

o Brett, building maven-plugins in offline mode with org/apache/maven/plugin/* removed will now give a nice error message. :)



git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@291124 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2005-09-23 14:23:08 +00:00
parent db6b1a8172
commit 24a108a674
35 changed files with 416 additions and 82 deletions

View File

@ -57,6 +57,12 @@ public class DefaultArtifactDeployer
ArtifactRepository localRepository )
throws ArtifactDeploymentException
{
if ( !wagonManager.isOnline() )
{
getLogger().warn( "System is offline. Cannot deploy artifact: " + artifact.getId() + "." );
return;
}
try
{
transformationManager.transformForDeployment( artifact, deploymentRepository, localRepository );

View File

@ -69,6 +69,8 @@ public class DefaultWagonManager
private Map mirrors = new HashMap();
private TransferListener downloadMonitor;
private boolean online = true;
public Wagon getWagon( String protocol )
throws UnsupportedProtocolException
@ -105,6 +107,8 @@ public class DefaultWagonManager
TransferListener downloadMonitor )
throws TransferFailedException
{
failIfNotOnline();
String protocol = repository.getProtocol();
Wagon wagon;
@ -277,7 +281,9 @@ public class DefaultWagonManager
throws TransferFailedException, ResourceDoesNotExistException, ChecksumFailedException
{
// TODO: better excetpions - transfer failed is not enough?
failIfNotOnline();
Wagon wagon;
ArtifactRepository mirror = getMirror( repository.getId() );
@ -454,6 +460,14 @@ public class DefaultWagonManager
}
}
private void failIfNotOnline() throws TransferFailedException
{
if ( !isOnline() )
{
throw new TransferFailedException( "System is offline." );
}
}
private void handleChecksumFailure( String checksumPolicy, String message, Throwable cause )
throws ChecksumFailedException
{
@ -640,4 +654,14 @@ public class DefaultWagonManager
mirrors.put( mirrorOf, mirror );
}
public void setOnline( boolean online )
{
this.online = online;
}
public boolean isOnline()
{
return online;
}
}

View File

@ -56,6 +56,10 @@ public interface WagonManager
void getArtifactMetadata( ArtifactMetadata metadata, ArtifactRepository remoteRepository, File destination,
String checksumPolicy )
throws TransferFailedException, ResourceDoesNotExistException;
void setOnline( boolean online );
boolean isOnline();
void addProxy( String protocol, String host, int port, String username, String password, String nonProxyHosts );

View File

@ -29,8 +29,6 @@ public class DefaultArtifactRepositoryFactory
private String globalChecksumPolicy;
private boolean globalEnable = true;
public ArtifactRepository createArtifactRepository( String id, String url,
ArtifactRepositoryLayout repositoryLayout )
{
@ -64,13 +62,6 @@ public class DefaultArtifactRepositoryFactory
releases.setChecksumPolicy( globalChecksumPolicy );
}
// TODO: needed, or can offline cover it?
if ( !globalEnable )
{
snapshots.setEnabled( false );
releases.setEnabled( false );
}
return new DefaultArtifactRepository( id, url, repositoryLayout, snapshots, releases );
}
@ -84,8 +75,11 @@ public class DefaultArtifactRepositoryFactory
this.globalChecksumPolicy = checksumPolicy;
}
/**
* @deprecated. Not needed, use WagonManager.set/isOnline() instead.
*/
public void setGlobalEnable( boolean enable )
{
this.globalEnable = enable;
// TODO: Remove this method from the API.
}
}

View File

@ -178,4 +178,16 @@ public abstract class AbstractRepositoryMetadata
AbstractRepositoryMetadata repoMetadata = (AbstractRepositoryMetadata) metadata;
this.metadata.merge( repoMetadata.getMetadata() );
}
public String extendedToString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( "\nRepository Metadata\n--------------------------" );
buffer.append( "\nGroupId: " ).append( getGroupId() );
buffer.append( "\nArtifactId: " ).append( getArtifactId() );
buffer.append( "\nMetadata Type: " ).append(getClass().getName() );
return buffer.toString();
}
}

View File

@ -183,6 +183,12 @@ public class DefaultRepositoryMetadataManager
ArtifactRepository remoteRepository )
throws ArtifactMetadataRetrievalException
{
if ( !wagonManager.isOnline() )
{
getLogger().debug( "System is offline. Cannot resolve metadata:\n" + metadata.extendedToString() + "\n\n" );
return;
}
File file = new File( localRepository.getBasedir(),
localRepository.pathOfLocalRepositoryMetadata( metadata, remoteRepository ) );
@ -199,6 +205,12 @@ public class DefaultRepositoryMetadataManager
String checksumPolicy )
throws ArtifactMetadataRetrievalException
{
if ( !wagonManager.isOnline() )
{
getLogger().debug( "System is offline. Cannot resolve metadata:\n" + metadata.extendedToString() + "\n\n" );
return;
}
try
{
wagonManager.getArtifactMetadata( metadata, repository, file, checksumPolicy );
@ -228,6 +240,12 @@ public class DefaultRepositoryMetadataManager
ArtifactRepository deploymentRepository )
throws ArtifactMetadataRetrievalException
{
if ( !wagonManager.isOnline() )
{
getLogger().warn( "System is offline. Cannot deploy metadata:\n" + metadata.extendedToString() + "\n\n" );
return;
}
getLogger().info( "Retrieving previous metadata from " + deploymentRepository.getId() );
File file = new File( localRepository.getBasedir(),

View File

@ -113,6 +113,13 @@ public class DefaultArtifactResolver
File destination = artifact.getFile();
if ( !destination.exists() || force )
{
if ( !wagonManager.isOnline() )
{
getLogger().debug( "System is offline. Cannot resolve artifact: " + artifact.getId() + "." );
return;
}
try
{
if ( artifact.getRepository() != null )

View File

@ -154,6 +154,15 @@ public abstract class AbstractVersionTransformation
boolean alreadyResolved = alreadyResolved( artifact );
if ( !alreadyResolved )
{
if ( !wagonManager.isOnline() )
{
LegacyArtifactMetadata metadata = createLegacyMetadata( artifact );
getLogger().debug( "System is offline. Cannot resolve metadata:\n" + metadata.extendedToString() + "\n\n" );
return null;
}
boolean checkedUpdates = false;
for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); )
{

View File

@ -126,6 +126,15 @@ public class SnapshotTransformation
{
RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata( artifact );
if ( !wagonManager.isOnline() )
{
getLogger().debug( "System is offline. Cannot resolve metadata:\n" + metadata.extendedToString() + "\n\n" );
getLogger().info( "System is offline. Assuming build number of 0 for " + metadata.getGroupId() + ":" + metadata.getArtifactId() + " snapshot." );
return 0;
}
getLogger().info( "Retrieving previous build number from " + remoteRepository.getId() );
repositoryMetadataManager.resolveAlways( metadata, localRepository, remoteRepository );

View File

@ -48,4 +48,16 @@ public abstract class AbstractArtifactMetadata
{
return artifact.getArtifactId();
}
public String extendedToString()
{
StringBuffer buffer = new StringBuffer();
buffer.append( "\nArtifact Metadata\n--------------------------" );
buffer.append( "\nGroupId: " ).append( getGroupId() );
buffer.append( "\nArtifactId: " ).append( getArtifactId() );
buffer.append( "\nMetadata Type: " ).append(getClass().getName() );
return buffer.toString();
}
}

View File

@ -78,4 +78,6 @@ public interface ArtifactMetadata
*/
void storeInLocalRepository( ArtifactRepository localRepository, ArtifactRepository remoteRepository )
throws ArtifactMetadataRetrievalException;
String extendedToString();
}

View File

@ -35,5 +35,8 @@ public interface ArtifactRepositoryFactory
void setGlobalChecksumPolicy( String checksumPolicy );
/**
* @deprecated. Not needed, use WagonManager.set/isOnline() instead.
*/
void setGlobalEnable( boolean enable );
}

View File

@ -41,18 +41,24 @@ public class ArtifactResolutionException
private List remoteRepositories;
private final String originalMessage;
private final String path;
public ArtifactResolutionException( String message, String groupId, String artifactId, String version, String type,
List remoteRepositories, String downloadUrl, List path, Throwable t )
{
super( constructMessage( message, groupId, artifactId, version, type, remoteRepositories, downloadUrl, path ),
t );
this.originalMessage = message;
this.groupId = groupId;
this.artifactId = artifactId;
this.type = type;
this.version = version;
this.remoteRepositories = remoteRepositories;
this.downloadUrl = downloadUrl;
this.path = constructArtifactPath( path );
}
public ArtifactResolutionException( String message, String groupId, String artifactId, String version, String type,
@ -66,16 +72,46 @@ public class ArtifactResolutionException
{
super( constructMessage( message, groupId, artifactId, version, type, remoteRepositories, downloadUrl, path ) );
this.originalMessage = message;
this.groupId = groupId;
this.artifactId = artifactId;
this.type = type;
this.version = version;
this.remoteRepositories = remoteRepositories;
this.downloadUrl = downloadUrl;
this.path = constructArtifactPath( path );
}
public String getOriginalMessage()
{
return originalMessage;
}
private static final String LS = System.getProperty( "line.separator" );
private static String constructArtifactPath( List path )
{
StringBuffer sb = new StringBuffer();
if ( path != null )
{
sb.append( LS );
sb.append( "Path to dependency: " );
sb.append( LS );
int num = 1;
for ( Iterator i = path.iterator(); i.hasNext(); )
{
sb.append( "\t" );
sb.append( num++ );
sb.append( ") " );
sb.append( i.next() );
sb.append( LS );
}
}
return sb.toString();
}
private static String constructMessage( String message, String groupId, String artifactId, String version,
String type, List remoteRepositories, String downloadUrl, List path )
{
@ -106,22 +142,8 @@ public class ArtifactResolutionException
}
}
if ( path != null )
{
sb.append( LS );
sb.append( "Path to dependency: " );
sb.append( LS );
int num = 1;
for ( Iterator i = path.iterator(); i.hasNext(); )
{
sb.append( "\t" );
sb.append( num++ );
sb.append( ") " );
sb.append( i.next() );
sb.append( LS );
}
sb.append( LS );
}
sb.append( constructArtifactPath( path ) );
sb.append( LS );
if ( downloadUrl != null && !type.equals( "pom" ) )
{
@ -168,6 +190,9 @@ public class ArtifactResolutionException
public ArtifactResolutionException( String message, Throwable cause )
{
super( message, cause );
this.originalMessage = message;
this.path = "";
}
public String getGroupId()
@ -199,4 +224,10 @@ public class ArtifactResolutionException
{
return downloadUrl;
}
public String getArtifactPath()
{
return path;
}
}

View File

@ -0,0 +1 @@
failOnErrorOutput=false

View File

@ -0,0 +1 @@
-o

View File

@ -0,0 +1 @@
target/classes/org/apache/maven/it0069/ProjectBasedThing.class

View File

@ -0,0 +1 @@
compile

View File

@ -0,0 +1,14 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.it0069</groupId>
<artifactId>maven-it0069</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.0-beta-2-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,9 @@
package org.apache.maven.it0069;
import org.apache.maven.project.MavenProject;
public class ProjectBasedThing
{
private MavenProject project;
}

View File

@ -0,0 +1 @@
-o

View File

@ -0,0 +1 @@
target/classes/org/apache/maven/it0069/ProjectBasedThing.class

View File

@ -0,0 +1 @@
compile

View File

@ -0,0 +1,14 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.it1014</groupId>
<artifactId>maven-it1014</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.3</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1 @@
rm ${artifact:commons-logging:commons-logging:1.0.3:jar}

View File

@ -0,0 +1,6 @@
package org.apache.maven.it0069;
public class ProjectBasedThing
{
}

View File

@ -103,7 +103,31 @@ public class DefaultMaven
{
if ( request.getSettings().isOffline() )
{
getLogger().info( "Maven is running in offline mode." );
getLogger().info( "\n\nNOTE: Maven is running in offline mode.\n\n" );
WagonManager wagonManager = null;
try
{
wagonManager = (WagonManager) container.lookup( WagonManager.ROLE );
wagonManager.setOnline( false );
}
catch ( ComponentLookupException e )
{
throw new ReactorException( "Cannot retrieve WagonManager in order to set offline mode.", e );
}
finally
{
try
{
container.release( wagonManager );
}
catch ( ComponentLifecycleException e )
{
getLogger().warn( "Cannot release WagonManager.", e );
}
}
}
try
@ -239,6 +263,8 @@ public class DefaultMaven
}
catch ( LifecycleExecutionException e )
{
logFatal( e );
throw new ReactorException( "Error executing project within the reactor", e );
}
@ -504,6 +530,19 @@ public class DefaultMaven
// ----------------------------------------------------------------------
// Reporting / Logging
// ----------------------------------------------------------------------
protected void logFatal( Throwable error )
{
line();
getLogger().error( "FATAL ERROR" );
line();
diagnoseError( error );
line();
}
protected void logError( MavenExecutionResponse r )
{
@ -513,8 +552,17 @@ public class DefaultMaven
line();
Throwable error = r.getException();
diagnoseError( r.getException() );
line();
stats( r.getStart(), r.getFinish() );
line();
}
private void diagnoseError( Throwable error )
{
String message = null;
if ( errorDiagnosers != null )
{
@ -538,13 +586,14 @@ public class DefaultMaven
line();
getLogger().error( "Cause: ", r.getException() );
// TODO: needs to honour -e
if ( getLogger().isDebugEnabled() )
{
getLogger().debug( "Trace:\n", error );
line();
line();
}
stats( r.getStart(), r.getFinish() );
line();
}
protected void logFailure( MavenExecutionResponse r, Throwable error, String longMessage )

View File

@ -413,7 +413,7 @@ public class MavenCli
ArtifactRepositoryFactory artifactRepositoryFactory = (ArtifactRepositoryFactory) embedder.lookup(
ArtifactRepositoryFactory.ROLE );
String url = settings.getLocalRepository();
if ( !url.startsWith( "file:" ) )
@ -427,8 +427,7 @@ public class MavenCli
if ( commandLine.hasOption( CLIManager.OFFLINE ) )
{
settings.setOffline( true );
artifactRepositoryFactory.setGlobalEnable( false );
snapshotPolicySet = true;
}

View File

@ -188,11 +188,6 @@ public class DefaultPluginManager
project.addPlugin( plugin );
}
catch ( PlexusContainerException e )
{
throw new PluginManagerException(
"Error occurred in the artifact container attempting to download plugin " + plugin.getKey(), e );
}
catch ( ArtifactResolutionException e )
{
String groupId = plugin.getGroupId();
@ -261,7 +256,7 @@ public class DefaultPluginManager
protected void addPlugin( Plugin plugin, Artifact pluginArtifact, MavenProject project,
ArtifactRepository localRepository )
throws ArtifactResolutionException, PlexusContainerException
throws ArtifactResolutionException, PluginManagerException
{
// TODO: share with MMS? Not sure if it belongs here
if ( project.getProjectReferences() != null && !project.getProjectReferences().isEmpty() )
@ -276,11 +271,24 @@ public class DefaultPluginManager
}
artifactResolver.resolve( pluginArtifact, project.getPluginArtifactRepositories(), localRepository );
if ( !pluginArtifact.isResolved() )
{
throw new PluginContainerException( plugin, "Cannot resolve artifact for plugin." );
}
PlexusContainer child = container.createChildContainer( plugin.getKey(),
Collections.singletonList( pluginArtifact.getFile() ),
Collections.EMPTY_MAP,
Collections.singletonList( pluginCollector ) );
PlexusContainer child;
try
{
child = container.createChildContainer( plugin.getKey(),
Collections.singletonList( pluginArtifact.getFile() ),
Collections.EMPTY_MAP,
Collections.singletonList( pluginCollector ) );
}
catch ( PlexusContainerException e )
{
throw new PluginContainerException( plugin, "Failed to create plugin container.", e );
}
// this plugin's descriptor should have been discovered in the child creation, so we should be able to
// circle around and set the artifacts and class realm

View File

@ -0,0 +1,38 @@
package org.apache.maven.plugin;
import org.apache.maven.model.Plugin;
public class PluginContainerException
extends PluginManagerException
{
private final Plugin plugin;
private final String originalMessage;
public PluginContainerException( Plugin plugin, String message, Exception e )
{
super( "Error configuring container for: " + plugin.getKey() + ". Message was: " + message, e );
this.plugin = plugin;
this.originalMessage = message;
}
public PluginContainerException( Plugin plugin, String message )
{
super( "Error configuring container for: " + plugin.getKey() + ". Message was: " + message );
this.plugin = plugin;
this.originalMessage = message;
}
public String getOriginalMessage()
{
return originalMessage;
}
public Plugin getPlugin()
{
return plugin;
}
}

View File

@ -18,7 +18,6 @@ package org.apache.maven.usability;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.TransitiveArtifactResolutionException;
import org.apache.maven.project.ProjectBuildingException;
public class ArtifactResolverDiagnoser
implements ErrorDiagnoser
@ -26,45 +25,37 @@ public class ArtifactResolverDiagnoser
public boolean canDiagnose( Throwable error )
{
return error instanceof ArtifactResolutionException;
return DiagnosisUtils.containsInCausality( error, ArtifactResolutionException.class );
}
public String diagnose( Throwable error )
{
Throwable root = DiagnosisUtils.getRootCause( error );
ArtifactResolutionException exception = (ArtifactResolutionException) DiagnosisUtils.getFromCausality( error, ArtifactResolutionException.class );
String message = null;
if ( root instanceof ProjectBuildingException )
StringBuffer message = new StringBuffer();
message.append( "Failed to resolve artifact." );
message.append( "\n");
message.append( "\nGroupId: " ).append( exception.getGroupId() );
message.append( "\nArtifactId: " ).append( exception.getArtifactId() );
message.append( "\nVersion: " ).append( exception.getVersion() );
message.append( "\nType: " ).append( exception.getType() );
if ( exception instanceof TransitiveArtifactResolutionException )
{
StringBuffer messageBuffer = new StringBuffer();
if ( DiagnosisUtils.containsInCausality( error, TransitiveArtifactResolutionException.class ) )
{
messageBuffer.append(
"Error while transitively resolving artifacts (transitive path trace currently unavailable):\n\n" );
}
else
{
messageBuffer.append( "Error while resolving artifacts:\n\n" );
}
messageBuffer.append( "Root Error:\n " ).append( root.getMessage() );
message = messageBuffer.toString();
message.append( exception.getArtifactPath() );
}
else
message.append( DiagnosisUtils.getOfflineWarning() );
Throwable root = DiagnosisUtils.getRootCause( exception );
if ( root != null )
{
StringBuffer messageBuffer = new StringBuffer();
messageBuffer.append( "Main Error:\n " ).append( error.getMessage() );
messageBuffer.append( "\n\nRoot error:\n " ).append( root.getMessage() );
message = messageBuffer.toString();
message.append( "\n\nRoot Cause: " ).append( root.getMessage() ).append( "\n" );
}
return message;
return message.toString();
}
}

View File

@ -23,6 +23,12 @@ public final class DiagnosisUtils
{
}
public static String getOfflineWarning()
{
return "\nNOTE: If Maven is executing in offline mode, some artifacts may be missing from your" +
"\nlocal repository.\n";
}
public static boolean containsInCausality( Throwable error, Class test )
{
Throwable cause = error;

View File

@ -0,0 +1,51 @@
package org.apache.maven.usability;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.PluginContainerException;
public class PluginContainerDiagnoser
implements ErrorDiagnoser
{
public boolean canDiagnose( Throwable error )
{
return DiagnosisUtils.containsInCausality( error, PluginContainerException.class );
}
public String diagnose( Throwable error )
{
PluginContainerException exception = (PluginContainerException) DiagnosisUtils.getFromCausality( error, PluginContainerException.class );
// this is a little hackish, but it's simple.
String originalMessage = exception.getOriginalMessage();
Plugin plugin = exception.getPlugin();
StringBuffer message = new StringBuffer();
message.append( "Failed to prepare plugin for execution.");
message.append( "\n" );
message.append( "\nGroupId: " ).append( plugin.getGroupId() );
message.append( "\nArtifactId: " ).append( plugin.getArtifactId() );
message.append( "\nVersion: " ).append( plugin.getVersion() );
message.append( "\nReason: " ).append( originalMessage );
if ( originalMessage.startsWith( "Cannot resolve artifact" ) )
{
message.append( DiagnosisUtils.getOfflineWarning() );
}
else
{
Throwable rootCause = DiagnosisUtils.getRootCause( exception );
if ( rootCause != null )
{
message.append( "\nRoot Cause: " ).append( rootCause.getMessage() );
}
}
message.append( "\n\n" );
return message.toString();
}
}

View File

@ -101,6 +101,16 @@
<role-hint>PluginConfigurationDiagnoser</role-hint>
<implementation>org.apache.maven.usability.PluginConfigurationDiagnoser</implementation>
</component>
<!--
|
|PluginContainerDiagnoser
|
-->
<component>
<role>org.apache.maven.usability.ErrorDiagnoser</role>
<role-hint>PluginContainerDiagnoser</role-hint>
<implementation>org.apache.maven.usability.PluginContainerDiagnoser</implementation>
</component>
<!--
|
|ArtifactResolverDiagnoser

View File

@ -961,8 +961,8 @@ public class PrepareReleaseMojo
String version;
try
{
version = pluginVersionManager.resolvePluginVersion( plugin.getGroupId(), plugin
.getArtifactId(), project, settings, localRepository, true );
version = pluginVersionManager.resolveReportPluginVersion( plugin.getGroupId(), plugin
.getArtifactId(), project, settings, localRepository );
}
catch ( PluginVersionResolutionException e )
{

View File

@ -346,7 +346,7 @@ public class DefaultMavenProjectBuilder
try
{
artifactResolver.resolve( projectArtifact, remoteArtifactRepositories, localRepository );
File file = projectArtifact.getFile();
model = readModel( file );