/**
* Base class for Sonar-plugin-packaging related tasks.
- *
+ *
* @author Evgeny Mandrikov
*/
public abstract class AbstractSonarPluginMojo extends AbstractMojo {
/**
* The Maven project.
- *
+ *
* @parameter expression="${project}"
* @required
* @readonly
/**
* Directory containing the generated JAR.
- *
+ *
* @parameter expression="${project.build.directory}"
* @required
*/
/**
* Directory containing the classes and resource files that should be packaged into the JAR.
- *
+ *
* @parameter expression="${project.build.outputDirectory}"
* @required
*/
/**
* The directory where the app is built.
- *
+ *
* @parameter expression="${project.build.directory}/${project.build.finalName}"
* @required
*/
/**
* Name of the generated JAR.
- *
+ *
* @parameter alias="jarName" expression="${jar.finalName}" default-value="${project.build.finalName}"
* @required
*/
/**
* Classifier to add to the artifact generated. If given, the artifact will be an attachment instead.
- *
+ *
* @parameter
*/
private String classifier;
/**
* Plugin key.
- *
+ *
* @parameter expression="${sonar.pluginKey}" default-value="${project.artifactId}"
*/
private String pluginKey;
/**
* Name of plugin class.
- *
+ *
* @parameter expression="${sonar.pluginClass}"
* @required
*/
*/
private String pluginIssueTrackerUrl;
+ /**
+ * @parameter
+ * @since 0.3
+ */
+ private boolean useChildFirstClassLoader = false;
+
/**
* @parameter expression="${sonar.skipDependenciesPackaging}"
*/
return pluginIssueTrackerUrl;
}
+ public boolean isUseChildFirstClassLoader() {
+ return useChildFirstClassLoader;
+ }
+
protected boolean isSkipDependenciesPackaging() {
return skipDependenciesPackaging;
}
- @SuppressWarnings({"unchecked"})
+ @SuppressWarnings( { "unchecked" })
protected Set<Artifact> getDependencyArtifacts() {
return getProject().getDependencyArtifacts();
}
return result;
}
- @SuppressWarnings({"unchecked"})
+ @SuppressWarnings( { "unchecked" })
protected Set<Artifact> getIncludedArtifacts() {
Set<Artifact> result = new HashSet<Artifact>();
Set<Artifact> artifacts = getProject().getArtifacts();
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
*/
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;
/**
* 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;
/**
* The archive configuration to use.
* See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
- *
+ *
* @parameter
*/
private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
/**
* The artifact repository to use.
- *
+ *
* @parameter expression="${localRepository}"
* @required
* @readonly
/**
* The artifact factory to use.
- *
+ *
* @component
* @required
* @readonly
/**
* The artifact metadata source to use.
- *
+ *
* @component
* @required
* @readonly
/**
* The artifact collector to use.
- *
+ *
* @component
* @required
* @readonly
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<String> libs = copyDependencies();
- if (!libs.isEmpty()) {
+ if ( !libs.isEmpty()) {
archiver.getArchiver().addDirectory(getAppDirectory(), getIncludes(), getExcludes());
archive.addManifestEntry(PluginManifest.DEPENDENCIES, StringUtils.join(libs, " "));
}
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");
}
}
return new File(basedir, finalName + classifier + ".jar");
}
-
private List<String> copyDependencies() throws IOException, DependencyTreeBuilderException {
List<String> ids = new ArrayList<String>();
List<String> libs = new ArrayList<String>();
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;
}
return false;
}
-
private Set<Artifact> getSonarProvidedArtifacts() throws DependencyTreeBuilderException {
Set<Artifact> result = new HashSet<Artifact>();
ArtifactFilter artifactFilter = new ScopeArtifactFilter(Artifact.SCOPE_RUNTIME);
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);
}
*/
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;
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 {
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;
private String termsConditionsUrl;
private Date buildDate;
private String issueTrackerUrl;
-
+ private boolean useChildFirstClassLoader = false;
/**
* Load the manifest from a JAR file.
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), ' ');
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();
*/
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;
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
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"));
}
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));
}
}