aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Foster2013-03-19 19:06:35 (EDT)
committerBob Foster2013-03-19 19:06:35 (EDT)
commit05b60e31cd254d3b504b6c967d4a45d3362f97de (patch)
treeb906097a9b2ab9cfa274c34dcae8a79c8d49fb9a
parent45d791d380308183fce3554bbb48dc7b0647493b (diff)
downloadorg.eclipse.hudson.core-05b60e31cd254d3b504b6c967d4a45d3362f97de.zip
org.eclipse.hudson.core-05b60e31cd254d3b504b6c967d4a45d3362f97de.tar.gz
org.eclipse.hudson.core-05b60e31cd254d3b504b6c967d4a45d3362f97de.tar.bz2
-rw-r--r--hudson-test-framework/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java9
-rw-r--r--hudson-test-framework/src/main/java/org/jvnet/hudson/test/MavenUtil.java223
2 files changed, 229 insertions, 3 deletions
diff --git a/hudson-test-framework/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java b/hudson-test-framework/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
index 9d295e7..7d664df 100644
--- a/hudson-test-framework/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
+++ b/hudson-test-framework/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java
@@ -143,8 +143,10 @@ import hudson.slaves.ComputerListener;
import java.util.concurrent.CountDownLatch;
import hudson.maven.MavenEmbedder;
+import hudson.maven.MavenRequest;
import hudson.security.*;
import hudson.util.SecurityFailedToInit;
+import java.nio.charset.Charset;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException;
import org.eclipse.hudson.HudsonServletContextListener;
@@ -1298,7 +1300,8 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
String dependencies = m.getMainAttributes().getValue("Plugin-Dependencies");
if (dependencies != null) {
- MavenEmbedder embedder = new MavenEmbedder(getClass().getClassLoader(), null);
+ MavenRequest mavenRequest = MavenUtil.createMavenRequest(new StreamTaskListener(System.out,Charset.defaultCharset()));
+ MavenEmbedder embedder = new MavenEmbedder(getClass().getClassLoader(), mavenRequest);
for (String dep : dependencies.split(",")) {
String[] tokens = dep.split(":");
String artifactId = tokens[0];
@@ -1307,7 +1310,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
// need to search multiple group IDs
// TODO: extend manifest to include groupID:artifactID:version
Exception resolutionError = null;
- for (String groupId : new String[]{"org.jvnet.hudson.plugins", "org.jvnet.hudson.main"}) {
+ for (String groupId : new String[]{"org.hudsonci.plugins", "org.jvnet.hudson.plugins", "org.jvnet.hudson.main"}) {
// first try to find it on the classpath.
// this takes advantage of Maven POM located in POM
@@ -1320,7 +1323,7 @@ public abstract class HudsonTestCase extends TestCase implements RootAction {
Artifact a;
a = embedder.createArtifact(groupId, artifactId, version, "compile"/*doesn't matter*/, "hpi");
try {
- embedder.resolve(a, Arrays.asList(embedder.createRepository("http://maven.glassfish.org/content/groups/public/", "repo")), embedder.getLocalRepository());
+ embedder.resolve(a, Arrays.asList(embedder.createRepository("https://oss.sonatype.org/content/repositories/releases/", "repo")), embedder.getLocalRepository());
dependencyJar = a.getFile();
} catch (AbstractArtifactResolutionException x) {
// could be a wrong groupId
diff --git a/hudson-test-framework/src/main/java/org/jvnet/hudson/test/MavenUtil.java b/hudson-test-framework/src/main/java/org/jvnet/hudson/test/MavenUtil.java
new file mode 100644
index 0000000..e012559
--- /dev/null
+++ b/hudson-test-framework/src/main/java/org/jvnet/hudson/test/MavenUtil.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2013 Hudson.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Hudson - initial API and implementation and/or initial documentation
+ */
+
+package org.jvnet.hudson.test;
+
+import hudson.AbortException;
+import hudson.maven.MavenEmbedder;
+import hudson.maven.MavenEmbedderException;
+import hudson.maven.MavenRequest;
+import hudson.model.TaskListener;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.logging.Logger;
+
+import org.apache.commons.io.IOUtils;
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+import org.apache.maven.model.building.ModelBuildingRequest;
+import org.apache.maven.cli.MavenLoggerManager;
+import org.codehaus.plexus.logging.console.ConsoleLogger;
+
+/**
+ * Just enough of MavenUtil from legacy-maven to fix test harness bug
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=403703
+ *
+ * TODO Move class back to Hudson?
+ *
+ * @author Bob Foster
+ */
+public class MavenUtil {
+
+ /**
+ * Create MavenRequest given only a TaskListener. Used by HudsonTestCase.
+ *
+ * @param listener
+ * @return MavenRequest
+ * @throws MavenEmbedderException
+ * @throws IOException
+ */
+ public static MavenRequest createMavenRequest(TaskListener listener) throws MavenEmbedderException, IOException {
+ Properties systemProperties = new Properties();
+
+ MavenRequest mavenRequest = new MavenRequest();
+
+ // make sure ~/.m2 exists to avoid http://www.nabble.com/BUG-Report-tf3401736.html
+ File m2Home = new File(MavenEmbedder.userHome, ".m2");
+ m2Home.mkdirs();
+ if(!m2Home.exists())
+ throw new AbortException("Failed to create "+m2Home);
+
+ mavenRequest.setUserSettingsFile( new File( m2Home, "settings.xml" ).getAbsolutePath() );
+
+ mavenRequest.setGlobalSettingsFile( new File( "conf/settings.xml" ).getAbsolutePath() );
+
+ mavenRequest.setUpdateSnapshots(false);
+
+ // TODO olamy check this sould be userProperties
+ mavenRequest.setSystemProperties(systemProperties);
+
+ EmbedderLoggerImpl logger =
+ new EmbedderLoggerImpl( listener, debugMavenEmbedder ? org.codehaus.plexus.logging.Logger.LEVEL_DEBUG
+ : org.codehaus.plexus.logging.Logger.LEVEL_INFO );
+ mavenRequest.setMavenLoggerManager( logger );
+
+ ClassLoader mavenEmbedderClassLoader = new MaskingClassLoader( MavenUtil.class.getClassLoader() );
+
+ {// are we loading the right components.xml? (and not from Maven that's running Jetty, if we are running in "mvn hudson-dev:run" or "mvn hpi:run"?
+ Enumeration<URL> e = mavenEmbedderClassLoader.getResources("META-INF/plexus/components.xml");
+ while (e.hasMoreElements()) {
+ URL url = e.nextElement();
+ LOGGER.fine("components.xml from "+url);
+ }
+ }
+
+ mavenRequest.setProcessPlugins( false );
+ mavenRequest.setResolveDependencies( false );
+ mavenRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MAVEN_2_0 );
+
+ return mavenRequest;
+ }
+
+ /**
+ * {@link MavenEmbedderLogger} implementation that
+ * sends output to {@link TaskListener}.
+ *
+ * @author Kohsuke Kawaguchi
+ */
+ private static final class EmbedderLoggerImpl extends MavenLoggerManager {
+ private final PrintStream logger;
+
+ public EmbedderLoggerImpl(TaskListener listener, int threshold) {
+ super(new ConsoleLogger( threshold, "hudson-logger" ));
+ logger = listener.getLogger();
+ }
+
+ private void print(String message, Throwable throwable, int threshold, String prefix) {
+ if (getThreshold() <= threshold) {
+ StringTokenizer tokens = new StringTokenizer(message,"\n");
+ while(tokens.hasMoreTokens()) {
+ logger.print(prefix);
+ logger.println(tokens.nextToken());
+ }
+
+ if (throwable!=null)
+ throwable.printStackTrace(logger);
+ }
+ }
+
+ public void debug(String message, Throwable throwable) {
+ print(message, throwable, org.codehaus.plexus.logging.Logger.LEVEL_DEBUG, "[DEBUG] ");
+ }
+
+ public void info(String message, Throwable throwable) {
+ print(message, throwable, org.codehaus.plexus.logging.Logger.LEVEL_INFO, "[INFO ] ");
+ }
+
+ public void warn(String message, Throwable throwable) {
+ print(message, throwable, org.codehaus.plexus.logging.Logger.LEVEL_WARN, "[WARN ] ");
+ }
+
+ public void error(String message, Throwable throwable) {
+ print(message, throwable, org.codehaus.plexus.logging.Logger.LEVEL_ERROR, "[ERROR] ");
+ }
+
+ public void fatalError(String message, Throwable throwable) {
+ print(message, throwable, org.codehaus.plexus.logging.Logger.LEVEL_FATAL, "[FATAL] ");
+ }
+ }
+
+ /**
+ * When we run in Jetty during development, embedded Maven will end up
+ * seeing some of the Maven class visible through Jetty, and this confuses it.
+ *
+ * <p>
+ * Specifically, embedded Maven will find all the component descriptors
+ * visible through Jetty, yet when it comes to loading classes, classworlds
+ * still load classes from local realms created inside embedder.
+ *
+ * <p>
+ * This classloader prevents this issue by hiding the component descriptor
+ * visible through Jetty.
+ */
+ private static final class MaskingClassLoader extends ClassLoader {
+
+ public MaskingClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+ public Enumeration<URL> getResources(String name) throws IOException {
+ final Enumeration<URL> e = super.getResources(name);
+ return new Enumeration<URL>() {
+ URL next;
+
+ public boolean hasMoreElements() {
+ fetch();
+ return next!=null;
+ }
+
+ public URL nextElement() {
+ fetch();
+ URL r = next;
+ next = null;
+ return r;
+ }
+
+ private void fetch() {
+ while(next==null && e.hasMoreElements()) {
+ next = e.nextElement();
+ if(shouldBeIgnored(next))
+ next = null;
+ }
+ }
+
+ private boolean shouldBeIgnored(URL url) {
+ String s = url.toExternalForm();
+ if(s.contains("maven-plugin-tools-api"))
+ return true;
+ // because RemoteClassLoader mangles the path, we can't check for plexus/components.xml,
+ // which would have otherwise made the test cheaper.
+ if(s.endsWith("components.xml")) {
+ BufferedReader r=null;
+ try {
+ // is this designated for interception purpose? If so, don't load them in the MavenEmbedder
+ // earlier I tried to use a marker file in the same directory, but that won't work
+ r = new BufferedReader(new InputStreamReader(url.openStream()));
+ for (int i=0; i<2; i++) {
+ String l = r.readLine();
+ if(l!=null && l.contains("MAVEN-INTERCEPTION-TO-BE-MASKED"))
+ return true;
+ }
+ } catch (IOException _) {
+ // let whoever requesting this resource re-discover an error and report it
+ } finally {
+ IOUtils.closeQuietly(r);
+ }
+ }
+ return false;
+ }
+ };
+ }
+ }
+
+ /**
+ * If set to true, maximize the logging level of Maven embedder.
+ */
+ public static boolean debugMavenEmbedder = Boolean.getBoolean( "debugMavenEmbedder" );
+
+ private static final Logger LOGGER = Logger.getLogger(MavenUtil.class.getName());
+}