From 249108122df5150cb69cf8500c74cfddea6dcaa6 Mon Sep 17 00:00:00 2001 From: Vincent Siveton Date: Sat, 1 Mar 2008 15:53:18 +0000 Subject: [PATCH] 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 --- .../maven/plugin/plugin/PluginReport.java | 6 +- .../plugin/plugin/XdocGeneratorMojo.java | 2 +- maven-plugin-tools-api/pom.xml | 20 ++ .../plugin/generator/PluginXdocGenerator.java | 21 +- .../maven/tools/plugin/util/PluginUtils.java | 59 ++++-- .../tools/plugin/util/PluginUtilsTest.java | 34 ++- .../plugin/util/stubs/MavenReportStub.java | 197 ++++++++++++++++++ .../tools/plugin/util/stubs/MojoStub.java | 100 +++++++++ 8 files changed, 413 insertions(+), 26 deletions(-) create mode 100644 maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MavenReportStub.java create mode 100644 maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MojoStub.java diff --git a/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/PluginReport.java b/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/PluginReport.java index 4722f16..5f29564 100644 --- a/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/PluginReport.java +++ b/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/PluginReport.java @@ -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 ); diff --git a/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/XdocGeneratorMojo.java b/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/XdocGeneratorMojo.java index a7a62ef..2d494d2 100644 --- a/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/XdocGeneratorMojo.java +++ b/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/XdocGeneratorMojo.java @@ -51,6 +51,6 @@ public class XdocGeneratorMojo /** {@inheritDoc} */ protected Generator createGenerator() { - return new PluginXdocGenerator(); + return new PluginXdocGenerator( project ); } } diff --git a/maven-plugin-tools-api/pom.xml b/maven-plugin-tools-api/pom.xml index 897b99e..30ba5f4 100644 --- a/maven-plugin-tools-api/pom.xml +++ b/maven-plugin-tools-api/pom.xml @@ -76,5 +76,25 @@ jtidy 4aug2000r7-dev + + + + org.apache.maven.reporting + maven-reporting-impl + 2.0.4 + test + + + + plexus + plexus-utils + + + + + org.apache.maven.shared + maven-plugin-testing-harness + test + diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java index 1a8c646..aa18605 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java @@ -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 Locale.ENGLISH as locale. + * Used only in test cases. */ public PluginXdocGenerator() { + this.project = null; + this.locale = Locale.ENGLISH; + } + + /** + * Constructor using Locale.ENGLISH 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( "" + getBundle( locale ).getString( "pluginxdoc.mojodescriptor.notice.note" ) diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java index 60e36f6..4419050 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/util/PluginUtils.java @@ -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 true is the Mojo implementation implements MavenReport, * false 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; } diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java index b9e9ea2..551b4cd 100644 --- a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/PluginUtilsTest.java @@ -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 = "" + "" + "testGroupId" + - "testArtifactId" + "pom" + "0.0.0" + - "" + ""; + String pattern = "" + "" + "testGroupId" + + "testArtifactId" + "pom" + "0.0.0" + + "" + ""; 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 ) ); + } } \ No newline at end of file diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MavenReportStub.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MavenReportStub.java new file mode 100644 index 0000000..eed9ea7 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MavenReportStub.java @@ -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(); + } +} diff --git a/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MojoStub.java b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MojoStub.java new file mode 100644 index 0000000..ca33e94 --- /dev/null +++ b/maven-plugin-tools-api/src/test/java/org/apache/maven/tools/plugin/util/stubs/MojoStub.java @@ -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 + { + + } +}