MPLUGIN-80: Detection of report goals always fails due to class loader separation

o improved PluginUtils#isMavenReport() to take car of project classloader
o added test case

git-svn-id: https://svn.apache.org/repos/asf/maven/plugin-tools/trunk@632607 13f79535-47bb-0310-9956-ffa450edef68
master
Vincent Siveton 2008-03-01 15:53:18 +00:00
parent 1fc6756949
commit 249108122d
8 changed files with 413 additions and 26 deletions

View File

@ -219,7 +219,7 @@ public class PluginReport
File outputDir = new File( getOutputDirectory() );
outputDir.mkdirs();
PluginXdocGenerator generator = new PluginXdocGenerator( locale );
PluginXdocGenerator generator = new PluginXdocGenerator( project, locale );
generator.execute( outputDir, pluginDescriptor );
}
catch ( IOException e )
@ -289,7 +289,7 @@ public class PluginReport
{
MojoDescriptor mojo = (MojoDescriptor) i.next();
if ( PluginUtils.isMavenReport( mojo.getImplementation() ) )
if ( PluginUtils.isMavenReport( mojo.getImplementation(), project ) )
{
hasMavenReport = true;
}
@ -337,7 +337,7 @@ public class PluginReport
tableCell( createLinkPatternedText( goalName, goalDocumentationLink ) );
if ( hasMavenReport )
{
if ( PluginUtils.isMavenReport( mojo.getImplementation() ) )
if ( PluginUtils.isMavenReport( mojo.getImplementation(), project ) )
{
sink.tableCell();
iconValid( locale );

View File

@ -51,6 +51,6 @@ public class XdocGeneratorMojo
/** {@inheritDoc} */
protected Generator createGenerator()
{
return new PluginXdocGenerator();
return new PluginXdocGenerator( project );
}
}

View File

@ -76,5 +76,25 @@
<artifactId>jtidy</artifactId>
<version>4aug2000r7-dev</version>
</dependency>
<!-- test -->
<dependency>
<groupId>org.apache.maven.reporting</groupId>
<artifactId>maven-reporting-impl</artifactId>
<version>2.0.4</version>
<scope>test</scope>
<exclusions>
<!-- Using org.codehaus.plexus:plexus-utils instead of -->
<exclusion>
<groupId>plexus</groupId>
<artifactId>plexus-utils</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -35,6 +35,7 @@ import java.util.regex.Pattern;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.util.PluginUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringInputStream;
@ -53,19 +54,35 @@ public class PluginXdocGenerator
{
private final Locale locale;
private final MavenProject project;
/**
* Default constructor using <code>Locale.ENGLISH</code> as locale.
* Used only in test cases.
*/
public PluginXdocGenerator()
{
this.project = null;
this.locale = Locale.ENGLISH;
}
/**
* Constructor using <code>Locale.ENGLISH</code> as locale.
*
* @param project not null Maven project.
*/
public PluginXdocGenerator( MavenProject project )
{
this.project = project;
this.locale = Locale.ENGLISH;
}
/**
* @param locale not null wanted locale.
*/
public PluginXdocGenerator( Locale locale )
public PluginXdocGenerator( MavenProject project, Locale locale )
{
this.project = project;
if ( locale == null )
{
this.locale = Locale.ENGLISH;
@ -182,7 +199,7 @@ public class PluginXdocGenerator
private void writeReportNotice( MojoDescriptor mojoDescriptor, XMLWriter w )
{
if ( PluginUtils.isMavenReport( mojoDescriptor.getImplementation() ) )
if ( PluginUtils.isMavenReport( mojoDescriptor.getImplementation(), project ) )
{
w.startElement( "p" );
w.writeMarkup( "<strong>" + getBundle( locale ).getString( "pluginxdoc.mojodescriptor.notice.note" )

View File

@ -19,12 +19,19 @@ package org.apache.maven.tools.plugin.util;
* under the License.
*/
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReport;
import org.codehaus.plexus.component.repository.ComponentDependency;
import org.codehaus.plexus.util.DirectoryScanner;
@ -153,37 +160,61 @@ public final class PluginUtils
}
/**
* @param impl a Mojo implementation
* @param impl a Mojo implementation, not null
* @param project a MavenProject instance, could be null
* @return <code>true</code> is the Mojo implementation implements <code>MavenReport</code>,
* <code>false</code> otherwise.
* @throws IllegalArgumentException if any
*/
public static boolean isMavenReport( String impl )
public static boolean isMavenReport( String impl, MavenProject project )
{
if ( impl == null )
{
throw new IllegalArgumentException( "mojo implementation should be declared" );
}
Object mojo = null;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if ( project != null )
{
List classPathStrings;
try
{
classPathStrings = project.getCompileClasspathElements();
}
catch ( DependencyResolutionRequiredException e )
{
throw new IllegalArgumentException( e );
}
List urls = new ArrayList( classPathStrings.size() );
for ( Iterator it = classPathStrings.iterator(); it.hasNext(); )
{
try
{
urls.add( new File( ( (String) it.next() ) ).toURL() );
}
catch ( MalformedURLException e )
{
throw new IllegalArgumentException( e );
}
}
URLClassLoader projectClassLoader = new URLClassLoader( (URL[]) urls.toArray( new URL[urls.size()] ),
classLoader );
classLoader = projectClassLoader;
}
Class clazz = null;
try
{
Class clazz = Class.forName( impl );
mojo = clazz.newInstance();
clazz = Class.forName( impl, false, classLoader );
}
catch ( ClassNotFoundException e )
{
return false;
}
catch ( InstantiationException e )
{
return false;
}
catch ( IllegalAccessException e )
{
return false;
}
if ( ( mojo != null ) && ( mojo instanceof MavenReport ) )
if ( MavenReport.class.isAssignableFrom( clazz ) )
{
return true;
}

View File

@ -19,8 +19,9 @@ package org.apache.maven.tools.plugin.util;
* under the License.
*/
import junit.framework.TestCase;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.testing.AbstractMojoTestCase;
import org.apache.maven.plugin.testing.stubs.MavenProjectStub;
import org.codehaus.plexus.component.repository.ComponentDependency;
import org.codehaus.plexus.util.xml.CompactXMLWriter;
import org.codehaus.plexus.util.xml.XMLWriter;
@ -32,9 +33,8 @@ import java.util.Collections;
* @author jdcasey
*/
public class PluginUtilsTest
extends TestCase
extends AbstractMojoTestCase
{
public void testShouldTrimArtifactIdToFindPluginId()
{
assertEquals( "artifactId", PluginDescriptor.getGoalPrefixFromArtifactId( "maven-artifactId-plugin" ) );
@ -64,9 +64,9 @@ public class PluginUtilsTest
String output = sWriter.toString();
String pattern = "<dependencies>" + "<dependency>" + "<groupId>testGroupId</groupId>" +
"<artifactId>testArtifactId</artifactId>" + "<type>pom</type>" + "<version>0.0.0</version>" +
"</dependency>" + "</dependencies>";
String pattern = "<dependencies>" + "<dependency>" + "<groupId>testGroupId</groupId>"
+ "<artifactId>testArtifactId</artifactId>" + "<type>pom</type>" + "<version>0.0.0</version>"
+ "</dependency>" + "</dependencies>";
assertEquals( pattern, output );
}
@ -96,4 +96,26 @@ public class PluginUtilsTest
assertEquals( 1, files.length );
}
public void testIsMavenReport()
throws Exception
{
try
{
PluginUtils.isMavenReport( null, null );
}
catch ( IllegalArgumentException e )
{
assertTrue( true );
}
String impl = "org.apache.maven.tools.plugin.util.stubs.MavenReportStub";
MavenProjectStub stub = new MavenProjectStub();
stub.setCompileSourceRoots( Collections.singletonList( getBasedir() + "/target/classes" ) );
assertTrue( PluginUtils.isMavenReport( impl, stub ) );
impl = "org.apache.maven.tools.plugin.util.stubs.MojoStub";
assertFalse( PluginUtils.isMavenReport( impl, stub ) );
}
}

View File

@ -0,0 +1,197 @@
package org.apache.maven.tools.plugin.util.stubs;
/*
* 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.Locale;
import java.util.Map;
import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.codehaus.doxia.sink.Sink;
/**
* Dummy report.
*
* @goal dummyReport
* @version $Id$
*/
public class MavenReportStub
extends AbstractMavenReport
{
/** {@inheritDoc} */
public boolean canGenerateReport()
{
return super.canGenerateReport();
}
/** {@inheritDoc} */
protected void closeReport()
{
super.closeReport();
}
/** {@inheritDoc} */
public void execute()
throws MojoExecutionException
{
super.execute();
}
/** {@inheritDoc} */
protected void executeReport( Locale locale )
throws MavenReportException
{
}
/** {@inheritDoc} */
public void generate( Sink sink, Locale locale )
throws MavenReportException
{
super.generate( sink, locale );
}
/** {@inheritDoc} */
public String getCategoryName()
{
return super.getCategoryName();
}
/** {@inheritDoc} */
protected String getOutputDirectory()
{
return null;
}
/** {@inheritDoc} */
protected MavenProject getProject()
{
return null;
}
/** {@inheritDoc} */
public File getReportOutputDirectory()
{
return super.getReportOutputDirectory();
}
/** {@inheritDoc} */
public org.apache.maven.doxia.sink.Sink getSink()
{
return super.getSink();
}
/** {@inheritDoc} */
protected Renderer getSiteRenderer()
{
return null;
}
/** {@inheritDoc} */
public boolean isExternalReport()
{
return super.isExternalReport();
}
/** {@inheritDoc} */
public void setReportOutputDirectory( File reportOutputDirectory )
{
super.setReportOutputDirectory( reportOutputDirectory );
}
/** {@inheritDoc} */
public Log getLog()
{
return super.getLog();
}
/** {@inheritDoc} */
public Map getPluginContext()
{
return super.getPluginContext();
}
/** {@inheritDoc} */
public void setLog( Log log )
{
super.setLog( log );
}
/** {@inheritDoc} */
public void setPluginContext( Map pluginContext )
{
super.setPluginContext( pluginContext );
}
/** {@inheritDoc} */
public String getDescription( Locale locale )
{
return null;
}
/** {@inheritDoc} */
public String getName( Locale locale )
{
return null;
}
/** {@inheritDoc} */
public String getOutputName()
{
return null;
}
/** {@inheritDoc} */
protected Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
/** {@inheritDoc} */
public boolean equals( Object obj )
{
return super.equals( obj );
}
/** {@inheritDoc} */
protected void finalize()
throws Throwable
{
super.finalize();
}
/** {@inheritDoc} */
public int hashCode()
{
return super.hashCode();
}
/** {@inheritDoc} */
public String toString()
{
return super.toString();
}
}

View File

@ -0,0 +1,100 @@
package org.apache.maven.tools.plugin.util.stubs;
/*
* 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.Map;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
/**
* Dummy Mojo.
*
* @goal dummy
* @version $Id$
*/
public class MojoStub
extends AbstractMojo
{
/** {@inheritDoc} */
public Log getLog()
{
return super.getLog();
}
/** {@inheritDoc} */
public Map getPluginContext()
{
return super.getPluginContext();
}
/** {@inheritDoc} */
public void setLog( Log log )
{
super.setLog( log );
}
/** {@inheritDoc} */
public void setPluginContext( Map pluginContext )
{
super.setPluginContext( pluginContext );
}
/** {@inheritDoc} */
protected Object clone()
throws CloneNotSupportedException
{
return super.clone();
}
/** {@inheritDoc} */
public boolean equals( Object obj )
{
return super.equals( obj );
}
/** {@inheritDoc} */
protected void finalize()
throws Throwable
{
super.finalize();
}
/** {@inheritDoc} */
public int hashCode()
{
return super.hashCode();
}
/** {@inheritDoc} */
public String toString()
{
return super.toString();
}
/** {@inheritDoc} */
public void execute()
throws MojoExecutionException, MojoFailureException
{
}
}