From ab7b786eb2cf0c683641d33e7decf24ceca80ea6 Mon Sep 17 00:00:00 2001 From: Godin Date: Sat, 16 Oct 2010 01:31:26 +0000 Subject: [PATCH] SONAR-1869: sonar-packaging-maven-plugin - should be possible to specify delegation model for plugin classloader --- .../mavenplugin/AbstractSonarPluginMojo.java | 32 ++++++++----- .../mavenplugin/SonarPluginMojo.java | 45 ++++++++++--------- .../updatecenter/common/PluginManifest.java | 25 ++++++++--- .../common/PluginManifestTest.java | 12 ++--- 4 files changed, 73 insertions(+), 41 deletions(-) diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java index fe6f4733348..eae8defb9ed 100644 --- a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/AbstractSonarPluginMojo.java @@ -32,7 +32,7 @@ import java.util.Set; /** * Base class for Sonar-plugin-packaging related tasks. - * + * * @author Evgeny Mandrikov */ public abstract class AbstractSonarPluginMojo extends AbstractMojo { @@ -42,7 +42,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * The Maven project. - * + * * @parameter expression="${project}" * @required * @readonly @@ -51,7 +51,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * Directory containing the generated JAR. - * + * * @parameter expression="${project.build.directory}" * @required */ @@ -59,7 +59,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * Directory containing the classes and resource files that should be packaged into the JAR. - * + * * @parameter expression="${project.build.outputDirectory}" * @required */ @@ -67,7 +67,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * The directory where the app is built. - * + * * @parameter expression="${project.build.directory}/${project.build.finalName}" * @required */ @@ -75,7 +75,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * Name of the generated JAR. - * + * * @parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}" * @required */ @@ -83,7 +83,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * Classifier to add to the artifact generated. If given, the artifact will be an attachment instead. - * + * * @parameter */ private String classifier; @@ -95,7 +95,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * Plugin key. - * + * * @parameter expression="${sonar.pluginKey}" default-value="${project.artifactId}" */ private String pluginKey; @@ -107,7 +107,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { /** * Name of plugin class. - * + * * @parameter expression="${sonar.pluginClass}" * @required */ @@ -133,6 +133,12 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { */ private String pluginIssueTrackerUrl; + /** + * @parameter + * @since 0.3 + */ + private boolean useChildFirstClassLoader = false; + /** * @parameter expression="${sonar.skipDependenciesPackaging}" */ @@ -193,11 +199,15 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { return pluginIssueTrackerUrl; } + public boolean isUseChildFirstClassLoader() { + return useChildFirstClassLoader; + } + protected boolean isSkipDependenciesPackaging() { return skipDependenciesPackaging; } - @SuppressWarnings({"unchecked"}) + @SuppressWarnings( { "unchecked" }) protected Set getDependencyArtifacts() { return getProject().getDependencyArtifacts(); } @@ -212,7 +222,7 @@ public abstract class AbstractSonarPluginMojo extends AbstractMojo { return result; } - @SuppressWarnings({"unchecked"}) + @SuppressWarnings( { "unchecked" }) protected Set getIncludedArtifacts() { Set result = new HashSet(); Set artifacts = getProject().getArtifacts(); diff --git a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java index 67fa2efa6fc..5a98cf40671 100644 --- a/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java +++ b/subprojects/sonar-update-center/sonar-packaging-maven-plugin/src/main/java/org/sonar/updatecenter/mavenplugin/SonarPluginMojo.java @@ -43,11 +43,15 @@ import org.sonar.updatecenter.common.PluginManifest; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * Build a Sonar Plugin from the current project. - * + * * @author Evgeny Mandrikov * @goal sonar-plugin * @phase package @@ -57,13 +61,13 @@ import java.util.*; */ public class SonarPluginMojo extends AbstractSonarPluginMojo { private static final String LIB_DIR = "META-INF/lib/"; - private static final String[] DEFAULT_EXCLUDES = new String[]{"**/package.html"}; - private static final String[] DEFAULT_INCLUDES = new String[]{"**/**"}; + private static final String[] DEFAULT_EXCLUDES = new String[] { "**/package.html" }; + private static final String[] DEFAULT_INCLUDES = new String[] { "**/**" }; /** * List of files to include. Specified as fileset patterns which are relative to the input directory whose contents * is being packaged into the JAR. - * + * * @parameter */ private String[] includes; @@ -71,14 +75,14 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { /** * List of files to exclude. Specified as fileset patterns which are relative to the input directory whose contents * is being packaged into the JAR. - * + * * @parameter */ private String[] excludes; /** * The Jar archiver. - * + * * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="jar" */ protected JarArchiver jarArchiver; @@ -86,7 +90,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { /** * The archive configuration to use. * See Maven Archiver Reference. - * + * * @parameter */ private MavenArchiveConfiguration archive = new MavenArchiveConfiguration(); @@ -100,7 +104,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { /** * The artifact repository to use. - * + * * @parameter expression="${localRepository}" * @required * @readonly @@ -109,7 +113,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { /** * The artifact factory to use. - * + * * @component * @required * @readonly @@ -118,7 +122,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { /** * The artifact metadata source to use. - * + * * @component * @required * @readonly @@ -127,7 +131,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { /** * The artifact collector to use. - * + * * @component * @required * @readonly @@ -177,12 +181,16 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { addManifestProperty("Build date", PluginManifest.BUILD_DATE, FormatUtils.toString(new Date(), true)); getLog().info("-------------------------------------------------------"); + if (isUseChildFirstClassLoader()) { + archive.addManifestEntry(PluginManifest.USE_CHILD_FIRST_CLASSLOADER, true); + } + if (isSkipDependenciesPackaging()) { getLog().info("Skip packaging of dependencies"); } else { List libs = copyDependencies(); - if (!libs.isEmpty()) { + if ( !libs.isEmpty()) { archiver.getArchiver().addDirectory(getAppDirectory(), getIncludes(), getExcludes()); archive.addManifestEntry(PluginManifest.DEPENDENCIES, StringUtils.join(libs, " ")); } @@ -228,9 +236,8 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { return null; } - private void checkPluginClass() throws MojoExecutionException { - if (!new File(getClassesDirectory(), getPluginClass().replace('.', '/') + ".class").exists()) { + if ( !new File(getClassesDirectory(), getPluginClass().replace('.', '/') + ".class").exists()) { throw new MojoExecutionException("Error assembling Sonar-plugin: Plugin-Class '" + getPluginClass() + "' not found"); } } @@ -244,7 +251,6 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { return new File(basedir, finalName + classifier + ".jar"); } - private List copyDependencies() throws IOException, DependencyTreeBuilderException { List ids = new ArrayList(); List libs = new ArrayList(); @@ -257,13 +263,13 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { ids.add(artifact.getDependencyConflictId()); } - if (!ids.isEmpty()) { + if ( !ids.isEmpty()) { getLog().info(getMessage("Following dependencies are packaged in the plugin:", ids)); getLog().info(new StringBuilder() .append("See following page for more details about plugin dependencies:\n") .append("\n\thttp://docs.codehaus.org/display/SONAR/Coding+a+plugin\n") .toString() - ); + ); } return libs; } @@ -300,7 +306,6 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { return false; } - private Set getSonarProvidedArtifacts() throws DependencyTreeBuilderException { Set result = new HashSet(); ArtifactFilter artifactFilter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME); @@ -322,7 +327,7 @@ public class SonarPluginMojo extends AbstractSonarPluginMojo { sonarArtifacts.add(dependency.getArtifact()); } - if (!Artifact.SCOPE_TEST.equals(dependency.getArtifact().getScope())) { + if ( !Artifact.SCOPE_TEST.equals(dependency.getArtifact().getScope())) { for (Object childDep : dependency.getChildren()) { searchForSonarProvidedArtifacts((DependencyNode) childDep, sonarArtifacts, isProvidedBySonar); } diff --git a/subprojects/sonar-update-center/sonar-update-center-common/src/main/java/org/sonar/updatecenter/common/PluginManifest.java b/subprojects/sonar-update-center/sonar-update-center-common/src/main/java/org/sonar/updatecenter/common/PluginManifest.java index 59c4265a70d..e3b7917e133 100644 --- a/subprojects/sonar-update-center/sonar-update-center-common/src/main/java/org/sonar/updatecenter/common/PluginManifest.java +++ b/subprojects/sonar-update-center/sonar-update-center-common/src/main/java/org/sonar/updatecenter/common/PluginManifest.java @@ -19,6 +19,8 @@ */ package org.sonar.updatecenter.common; +import static org.sonar.updatecenter.common.FormatUtils.toDate; + import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ReflectionToStringBuilder; @@ -29,11 +31,9 @@ import java.util.jar.Attributes; import java.util.jar.JarFile; import java.util.jar.Manifest; -import static org.sonar.updatecenter.common.FormatUtils.toDate; - /** - * This class loads Sonar plugin metadata from JAR manifest - * + * This class loads Sonar plugin metadata from JAR manifest. + * * @since 2.2 */ public final class PluginManifest { @@ -53,6 +53,11 @@ public final class PluginManifest { public static final String BUILD_DATE = "Build-Date"; public static final String ISSUE_TRACKER_URL = "Plugin-IssueTrackerUrl"; + /** + * @since 0.3 + */ + public static final String USE_CHILD_FIRST_CLASSLOADER = "Plugin-ChildFirstClassLoader"; + private String key; private String name; private String mainClass; @@ -67,7 +72,7 @@ public final class PluginManifest { private String termsConditionsUrl; private Date buildDate; private String issueTrackerUrl; - + private boolean useChildFirstClassLoader = false; /** * Load the manifest from a JAR file. @@ -109,6 +114,7 @@ public final class PluginManifest { this.sonarVersion = attributes.getValue(SONAR_VERSION); this.issueTrackerUrl = attributes.getValue(ISSUE_TRACKER_URL); this.buildDate = toDate(attributes.getValue(BUILD_DATE), true); + this.useChildFirstClassLoader = StringUtils.equalsIgnoreCase(attributes.getValue(USE_CHILD_FIRST_CLASSLOADER), "true"); String deps = attributes.getValue(DEPENDENCIES); this.dependencies = StringUtils.split(StringUtils.defaultString(deps), ' '); @@ -240,6 +246,15 @@ public final class PluginManifest { return this; } + public boolean isUseChildFirstClassLoader() { + return useChildFirstClassLoader; + } + + public PluginManifest setUseChildFirstClassLoader(boolean useChildFirstClassLoader) { + this.useChildFirstClassLoader = useChildFirstClassLoader; + return this; + } + @Override public String toString() { return new ReflectionToStringBuilder(this).toString(); diff --git a/subprojects/sonar-update-center/sonar-update-center-common/src/test/java/org/sonar/updatecenter/common/PluginManifestTest.java b/subprojects/sonar-update-center/sonar-update-center-common/src/test/java/org/sonar/updatecenter/common/PluginManifestTest.java index ac00a6ecf26..70d3dd666a4 100644 --- a/subprojects/sonar-update-center/sonar-update-center-common/src/test/java/org/sonar/updatecenter/common/PluginManifestTest.java +++ b/subprojects/sonar-update-center/sonar-update-center-common/src/test/java/org/sonar/updatecenter/common/PluginManifestTest.java @@ -19,6 +19,11 @@ */ package org.sonar.updatecenter.common; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsNull.nullValue; +import static org.hamcrest.number.OrderingComparisons.greaterThan; +import static org.junit.Assert.assertThat; + import org.junit.Test; import java.io.File; @@ -26,11 +31,6 @@ import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNull.nullValue; -import static org.hamcrest.number.OrderingComparisons.greaterThan; -import static org.junit.Assert.assertThat; - public class PluginManifestTest { @Test @@ -42,6 +42,7 @@ public class PluginManifestTest { assertThat(manifest.getName(), is("Checkstyle")); assertThat(manifest.getMainClass(), is("org.sonar.plugins.checkstyle.CheckstylePlugin")); assertThat(manifest.getVersion().length(), greaterThan(1)); + assertThat(manifest.isUseChildFirstClassLoader(), is(false)); assertThat(manifest.getDependencies().length, is(4)); assertThat(manifest.getDependencies()[0], is("META-INF/lib/antlr-2.7.6.jar")); } @@ -54,6 +55,7 @@ public class PluginManifestTest { assertThat(manifest.getKey(), nullValue()); assertThat(manifest.getName(), nullValue()); assertThat(manifest.getMainClass(), is("org.sonar.plugins.checkstyle.CheckstylePlugin")); + assertThat(manifest.isUseChildFirstClassLoader(), is(false)); assertThat(manifest.getDependencies().length, is(0)); } } -- 2.39.5