@@ -17,7 +17,7 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper; | |||
package org.sonar.runner; | |||
import java.io.IOException; | |||
import java.net.URL; | |||
@@ -27,11 +27,11 @@ import java.util.Enumeration; | |||
/** | |||
* Special {@link URLClassLoader} to execute Sonar, which restricts loading from parent. | |||
*/ | |||
public class BootstrapClassLoader extends URLClassLoader { | |||
class BootstrapClassLoader extends URLClassLoader { | |||
private final String[] unmaskedPackages; | |||
public BootstrapClassLoader(ClassLoader parent, String... unmaskedPackages) { | |||
BootstrapClassLoader(ClassLoader parent, String... unmaskedPackages) { | |||
super(new URL[0], parent); | |||
this.unmaskedPackages = unmaskedPackages; | |||
} | |||
@@ -56,6 +56,9 @@ public class BootstrapClassLoader extends URLClassLoader { | |||
* @return true, if class can be loaded from parent ClassLoader | |||
*/ | |||
boolean canLoadFromParent(String name) { | |||
if (name.startsWith("org.sonar.runner.") && !name.startsWith("org.sonar.runner.batch.")) { | |||
return true; | |||
} | |||
for (String pkg : unmaskedPackages) { | |||
if (name.startsWith(pkg + ".")) { | |||
return true; |
@@ -17,18 +17,9 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper; | |||
package org.sonar.runner; | |||
import org.sonar.runner.internal.bootstrapper.utils.PrivateIOUtils; | |||
import org.sonar.runner.utils.SonarRunnerVersion; | |||
import java.io.File; | |||
import java.io.FileOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.InputStreamReader; | |||
import java.io.Reader; | |||
import java.io.*; | |||
import java.net.HttpURLConnection; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
@@ -38,13 +29,12 @@ import java.util.List; | |||
/** | |||
* Bootstrapper used to download everything from the server and create the correct classloader required to execute a Sonar analysis in isolation. | |||
*/ | |||
public class Bootstrapper { | |||
private static final String VERSION_PATH = "/api/server/version"; | |||
private static final String BATCH_PATH = "/batch/"; | |||
class Bootstrapper { | |||
public static final int CONNECT_TIMEOUT_MILLISECONDS = 30000; | |||
public static final int READ_TIMEOUT_MILLISECONDS = 60000; | |||
static final String VERSION_PATH = "/api/server/version"; | |||
static final String BATCH_PATH = "/batch/"; | |||
static final int CONNECT_TIMEOUT_MILLISECONDS = 30000; | |||
static final int READ_TIMEOUT_MILLISECONDS = 60000; | |||
private File bootDir; | |||
private String serverUrl; | |||
@@ -54,7 +44,7 @@ public class Bootstrapper { | |||
/** | |||
* @param productToken part of User-Agent request-header field - see http://tools.ietf.org/html/rfc1945#section-10.15 | |||
*/ | |||
public Bootstrapper(String productToken, String serverUrl, File workDir) { | |||
Bootstrapper(String productToken, String serverUrl, File workDir) { | |||
this.productToken = productToken; | |||
bootDir = new File(workDir, "batch"); | |||
bootDir.mkdirs(); | |||
@@ -68,19 +58,19 @@ public class Bootstrapper { | |||
/** | |||
* @return server url | |||
*/ | |||
public String getServerUrl() { | |||
String getServerUrl() { | |||
return serverUrl; | |||
} | |||
/** | |||
* @return server version | |||
*/ | |||
public String getServerVersion() { | |||
String getServerVersion() { | |||
if (serverVersion == null) { | |||
try { | |||
serverVersion = remoteContent(VERSION_PATH); | |||
} catch (IOException e) { | |||
throw new BootstrapException(e.getMessage(), e); | |||
throw new IllegalStateException("Fail to request server version", e); | |||
} | |||
} | |||
return serverVersion; | |||
@@ -89,12 +79,12 @@ public class Bootstrapper { | |||
/** | |||
* Download batch files from server and creates {@link BootstrapClassLoader}. | |||
* To use this method version of Sonar should be at least 2.6. | |||
* | |||
* @param urls additional URLs for loading classes and resources | |||
* @param parent parent ClassLoader | |||
* | |||
* @param urls additional URLs for loading classes and resources | |||
* @param parent parent ClassLoader | |||
* @param unmaskedPackages only classes and resources from those packages would be available for loading from parent | |||
*/ | |||
public BootstrapClassLoader createClassLoader(URL[] urls, ClassLoader parent, String... unmaskedPackages) { | |||
BootstrapClassLoader createClassLoader(URL[] urls, ClassLoader parent, String... unmaskedPackages) { | |||
BootstrapClassLoader classLoader = new BootstrapClassLoader(parent, unmaskedPackages); | |||
List<File> files = downloadBatchFiles(); | |||
for (URL url : urls) { | |||
@@ -104,7 +94,7 @@ public class Bootstrapper { | |||
try { | |||
classLoader.addURL(file.toURI().toURL()); | |||
} catch (MalformedURLException e) { | |||
throw new BootstrapException(e); | |||
throw new IllegalStateException("Fail to create classloader", e); | |||
} | |||
} | |||
return classLoader; | |||
@@ -118,14 +108,14 @@ public class Bootstrapper { | |||
HttpURLConnection connection = newHttpConnection(new URL(fullUrl)); | |||
output = new FileOutputStream(toFile, false); | |||
input = connection.getInputStream(); | |||
PrivateIOUtils.copyLarge(input, output); | |||
IOUtils.copyLarge(input, output); | |||
} catch (IOException e) { | |||
PrivateIOUtils.closeQuietly(output); | |||
PrivateIOUtils.deleteFileQuietly(toFile); | |||
throw new BootstrapException("Fail to download the file: " + fullUrl, e); | |||
IOUtils.closeQuietly(output); | |||
IOUtils.deleteFileQuietly(toFile); | |||
throw new IllegalStateException("Fail to download the file: " + fullUrl, e); | |||
} finally { | |||
PrivateIOUtils.closeQuietly(input); | |||
PrivateIOUtils.closeQuietly(output); | |||
IOUtils.closeQuietly(input); | |||
IOUtils.closeQuietly(output); | |||
} | |||
} | |||
@@ -138,9 +128,9 @@ public class Bootstrapper { | |||
if (statusCode != HttpURLConnection.HTTP_OK) { | |||
throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode); | |||
} | |||
return PrivateIOUtils.toString(reader); | |||
return IOUtils.toString(reader); | |||
} finally { | |||
PrivateIOUtils.closeQuietly(reader); | |||
IOUtils.closeQuietly(reader); | |||
conn.disconnect(); | |||
} | |||
} | |||
@@ -149,7 +139,7 @@ public class Bootstrapper { | |||
* By convention, the product tokens are listed in order of their significance for identifying the application. | |||
*/ | |||
String getUserAgent() { | |||
return "sonar-bootstrapper/" + SonarRunnerVersion.getVersion() + " " + productToken; | |||
return "sonar-bootstrapper/" + Version.getVersion() + " " + productToken; | |||
} | |||
HttpURLConnection newHttpConnection(URL url) throws IOException { | |||
@@ -173,7 +163,7 @@ public class Bootstrapper { | |||
} | |||
return files; | |||
} catch (Exception e) { | |||
throw new BootstrapException(e); | |||
throw new IllegalStateException("Fail to download libraries from server", e); | |||
} | |||
} | |||
} |
@@ -17,24 +17,17 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper.utils; | |||
package org.sonar.runner; | |||
import java.io.Closeable; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.OutputStream; | |||
import java.io.Reader; | |||
import java.io.StringWriter; | |||
import java.io.Writer; | |||
import java.io.*; | |||
/** | |||
* Internal class used only by the Runner as we don't want it to depend on third-party libs. | |||
* This class should not be used by Sonar Runner consumers. | |||
* This class should not be used by Sonar Runner consumers. | |||
*/ | |||
public final class PrivateIOUtils { | |||
final class IOUtils { | |||
private PrivateIOUtils() { | |||
private IOUtils() { | |||
// only static methods | |||
} | |||
@@ -46,7 +39,7 @@ public final class PrivateIOUtils { | |||
/** | |||
* Unconditionally close a <code>Closeable</code>. | |||
*/ | |||
public static void closeQuietly(Closeable closeable) { | |||
static void closeQuietly(Closeable closeable) { | |||
try { | |||
if (closeable != null) { | |||
closeable.close(); | |||
@@ -58,7 +51,7 @@ public final class PrivateIOUtils { | |||
/** | |||
* Get the contents of a <code>Reader</code> as a String. | |||
*/ | |||
public static String toString(Reader input) throws IOException { | |||
static String toString(Reader input) throws IOException { | |||
StringWriter sw = new StringWriter(); | |||
copyLarge(input, sw); | |||
return sw.toString(); | |||
@@ -67,7 +60,7 @@ public final class PrivateIOUtils { | |||
/** | |||
* Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>. | |||
*/ | |||
public static long copyLarge(InputStream input, OutputStream output) throws IOException { | |||
static long copyLarge(InputStream input, OutputStream output) throws IOException { | |||
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; | |||
long count = 0; | |||
int n = 0; | |||
@@ -81,7 +74,7 @@ public final class PrivateIOUtils { | |||
/** | |||
* Copy chars from a <code>Reader</code> to a <code>Writer</code>. | |||
*/ | |||
public static long copyLarge(Reader input, Writer output) throws IOException { | |||
static long copyLarge(Reader input, Writer output) throws IOException { | |||
char[] buffer = new char[DEFAULT_BUFFER_SIZE]; | |||
long count = 0; | |||
int n = 0; | |||
@@ -95,7 +88,7 @@ public final class PrivateIOUtils { | |||
/** | |||
* Deletes a file (not a directory). | |||
*/ | |||
public static boolean deleteFileQuietly(File file) { | |||
static boolean deleteFileQuietly(File file) { | |||
if (file == null) { | |||
return false; | |||
} |
@@ -20,9 +20,6 @@ | |||
package org.sonar.runner; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.runner.internal.bootstrapper.BootstrapException; | |||
import org.sonar.runner.internal.bootstrapper.utils.PrivateIOUtils; | |||
import org.sonar.runner.utils.SonarRunnerVersion; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
@@ -67,7 +64,7 @@ public final class Main { | |||
try { | |||
Properties props = loadProperties(args); | |||
Runner runner = Runner.create(props); | |||
Logs.info("Runner version: " + SonarRunnerVersion.getVersion()); | |||
Logs.info("Runner version: " + Version.getVersion()); | |||
Logs.info("Java version: " + System.getProperty("java.version", "<unknown>") | |||
+ ", vendor: " + System.getProperty("java.vendor", "<unknown>")); | |||
Logs.info("OS name: \"" + System.getProperty("os.name") + "\", version: \"" + System.getProperty("os.version") + "\", arch: \"" + System.getProperty("os.arch") + "\""); | |||
@@ -154,10 +151,10 @@ public final class Main { | |||
return properties; | |||
} catch (Exception e) { | |||
throw new BootstrapException(e); | |||
throw new IllegalStateException("Fail to load file: " + file.getAbsolutePath(), e); | |||
} finally { | |||
PrivateIOUtils.closeQuietly(in); | |||
IOUtils.closeQuietly(in); | |||
} | |||
} | |||
@@ -19,15 +19,11 @@ | |||
*/ | |||
package org.sonar.runner; | |||
import org.sonar.runner.internal.bootstrapper.BootstrapClassLoader; | |||
import org.sonar.runner.internal.bootstrapper.BootstrapException; | |||
import org.sonar.runner.internal.bootstrapper.Bootstrapper; | |||
import org.sonar.runner.utils.SonarRunnerVersion; | |||
import java.io.File; | |||
import java.lang.reflect.Constructor; | |||
import java.lang.reflect.InvocationTargetException; | |||
import java.lang.reflect.Method; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
@@ -48,14 +44,14 @@ import java.util.Properties; | |||
* set via {@link #setEnvironmentInformation(String, String)} method)</li> | |||
* <li>... plus all the other Sonar and Sonar plugins properties.</li> | |||
* </ul> | |||
* | |||
* | |||
* @since 1.1 | |||
*/ | |||
public final class Runner { | |||
/** | |||
* Old property used to activate debug level for logging. | |||
* | |||
* | |||
* @deprecated Replaced by sonar.verbose since 1.2 | |||
*/ | |||
@Deprecated | |||
@@ -63,14 +59,14 @@ public final class Runner { | |||
/** | |||
* Property used to increase logging information. | |||
* | |||
* | |||
* @since 1.2 | |||
*/ | |||
public static final String PROPERTY_VERBOSE = "sonar.verbose"; | |||
/** | |||
* Property used to specify the working directory for the runner. May be a relative or absolute path. | |||
* | |||
* Property used to specify the working directory for the runner. May be a relative or absolute path. | |||
* | |||
* @since 1.4 | |||
*/ | |||
public static final String PROPERTY_WORK_DIRECTORY = "sonar.working.directory"; | |||
@@ -82,21 +78,21 @@ public final class Runner { | |||
/** | |||
* Property used to specify the base directory of the project to analyse. | |||
* | |||
* | |||
* @since 1.5 | |||
*/ | |||
public static final String PROPERTY_SONAR_PROJECT_BASEDIR = "sonar.projectBaseDir"; | |||
/** | |||
* Property used to specify the name of the tool that will run a Sonar analysis. | |||
* | |||
* | |||
* @since 1.5 | |||
*/ | |||
public static final String PROPERTY_ENVIRONMENT_INFORMATION_KEY = "sonar.environment.information.key"; | |||
/** | |||
* Property used to specify the version of the tool that will run a Sonar analysis. | |||
* | |||
* | |||
* @since 1.5 | |||
*/ | |||
public static final String PROPERTY_ENVIRONMENT_INFORMATION_VERSION = "sonar.environment.information.version"; | |||
@@ -117,7 +113,7 @@ public final class Runner { | |||
this.unmaskedPackages = new String[0]; | |||
// set the default values for the Sonar Runner - they can be overriden with #setEnvironmentInformation | |||
this.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, "Runner"); | |||
this.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, SonarRunnerVersion.getVersion()); | |||
this.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, Version.getVersion()); | |||
// and init the directories | |||
initDirs(); | |||
} | |||
@@ -141,7 +137,7 @@ public final class Runner { | |||
* Runs a Sonar analysis. | |||
*/ | |||
public void execute() { | |||
Bootstrapper bootstrapper = new Bootstrapper("SonarRunner/" + SonarRunnerVersion.getVersion(), getSonarServerURL(), getWorkDir()); | |||
Bootstrapper bootstrapper = new Bootstrapper("SonarRunner/" + Version.getVersion(), getSonarServerURL(), getWorkDir()); | |||
checkSonarVersion(bootstrapper); | |||
delegateExecution(createClassLoader(bootstrapper)); | |||
} | |||
@@ -200,17 +196,46 @@ public final class Runner { | |||
protected void checkSonarVersion(Bootstrapper bootstrapper) { | |||
String serverVersion = bootstrapper.getServerVersion(); | |||
if (isUnsupportedVersion(serverVersion)) { | |||
throw new BootstrapException("Sonar " + serverVersion | |||
+ " does not support Standalone Runner. Please upgrade Sonar to version 2.11 or more."); | |||
throw new RunnerException("Sonar " + serverVersion | |||
+ " is not supported. Please upgrade Sonar to version 2.11 or more."); | |||
} | |||
} | |||
private BootstrapClassLoader createClassLoader(Bootstrapper bootstrapper) { | |||
URL url = getClass().getProtectionDomain().getCodeSource().getLocation(); | |||
URL url = getJarPath(); | |||
return bootstrapper.createClassLoader( | |||
new URL[] {url}, // Add JAR with Sonar Runner - it's a Jar which contains this class | |||
getClass().getClassLoader(), | |||
unmaskedPackages); | |||
new URL[]{url}, // Add JAR with Sonar Runner - it's a Jar which contains this class | |||
getClass().getClassLoader(), | |||
unmaskedPackages); | |||
} | |||
/** | |||
* For unknown reasons <code>getClass().getProtectionDomain().getCodeSource().getLocation()</code> doesn't work under Ant 1.7.0. | |||
* So this is a workaround. | |||
* | |||
* @return Jar which contains this class | |||
*/ | |||
public static URL getJarPath() { | |||
String pathToClass = "/" + Runner.class.getName().replace('.', '/') + ".class"; | |||
URL url = Runner.class.getResource(pathToClass); | |||
if (url != null) { | |||
String path = url.toString(); | |||
String uri = null; | |||
if (path.startsWith("jar:file:")) { | |||
int bang = path.indexOf('!'); | |||
uri = path.substring(4, bang); | |||
} else if (path.startsWith("file:")) { | |||
int tail = path.indexOf(pathToClass); | |||
uri = path.substring(0, tail); | |||
} | |||
if (uri != null) { | |||
try { | |||
return new URL(uri); | |||
} catch (MalformedURLException e) { // NOSONAR | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
static boolean isUnsupportedVersion(String version) { | |||
@@ -226,26 +251,21 @@ public final class Runner { | |||
return version.startsWith(prefix + ".") || version.equals(prefix); | |||
} | |||
/** | |||
* Loads Launcher class from specified {@link org.sonar.batch.bootstrapper.BootstrapClassLoader} and passes control to it. | |||
* | |||
* @see Launcher#execute() | |||
*/ | |||
private void delegateExecution(BootstrapClassLoader sonarClassLoader) { | |||
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); | |||
try { | |||
Thread.currentThread().setContextClassLoader(sonarClassLoader); | |||
Class<?> launcherClass = sonarClassLoader.findClass("org.sonar.runner.internal.batch.Launcher"); | |||
Class<?> launcherClass = sonarClassLoader.findClass("org.sonar.runner.batch.Launcher"); | |||
Constructor<?> constructor = launcherClass.getConstructor(Properties.class, List.class); | |||
Object launcher = constructor.newInstance(getProperties(), containerExtensions); | |||
Method method = launcherClass.getMethod("execute"); | |||
method.invoke(launcher); | |||
} catch (InvocationTargetException e) { | |||
// Unwrap original exception | |||
throw new BootstrapException(e.getTargetException()); | |||
throw new RunnerException(e.getTargetException()); | |||
} catch (Exception e) { | |||
// Catch all other exceptions, which relates to reflection | |||
throw new BootstrapException(e); | |||
throw new RunnerException(e); | |||
} finally { | |||
Thread.currentThread().setContextClassLoader(oldContextClassLoader); | |||
} | |||
@@ -253,8 +273,8 @@ public final class Runner { | |||
/** | |||
* Allows to overwrite the environment information when Sonar Runner is embedded in a specific tool (for instance, with the Sonar Ant Task). | |||
* | |||
* @param key the key of the tool that embeds Sonar Runner | |||
* | |||
* @param key the key of the tool that embeds Sonar Runner | |||
* @param version the version of this tool | |||
*/ | |||
public void setEnvironmentInformation(String key, String version) { |
@@ -19,8 +19,6 @@ | |||
*/ | |||
package org.sonar.runner; | |||
import com.google.common.annotations.VisibleForTesting; | |||
class Stats { | |||
private long startTime; | |||
@@ -44,7 +42,6 @@ class Stats { | |||
return this; | |||
} | |||
@VisibleForTesting | |||
static String formatTime(long time) { | |||
long h = time / (60 * 60 * 1000); | |||
long m = (time - h * 60 * 60 * 1000) / (60 * 1000); |
@@ -17,15 +17,13 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.utils; | |||
import org.sonar.runner.internal.bootstrapper.utils.PrivateIOUtils; | |||
package org.sonar.runner; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.util.Properties; | |||
public enum SonarRunnerVersion { | |||
public enum Version { | |||
INSTANCE; | |||
@@ -36,7 +34,7 @@ public enum SonarRunnerVersion { | |||
return INSTANCE.version; | |||
} | |||
private SonarRunnerVersion() { | |||
private Version() { | |||
InputStream input = getClass().getResourceAsStream(PROPERTIES_PATH); | |||
try { | |||
Properties properties = new Properties(); | |||
@@ -48,7 +46,7 @@ public enum SonarRunnerVersion { | |||
this.version = ""; | |||
} finally { | |||
PrivateIOUtils.closeQuietly(input); | |||
IOUtils.closeQuietly(input); | |||
} | |||
} | |||
} |
@@ -17,18 +17,13 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.batch; | |||
package org.sonar.runner.batch; | |||
import ch.qos.logback.classic.LoggerContext; | |||
import ch.qos.logback.classic.joran.JoranConfigurator; | |||
import ch.qos.logback.core.joran.spi.JoranException; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.apache.commons.configuration.CompositeConfiguration; | |||
import org.apache.commons.configuration.Configuration; | |||
import org.apache.commons.configuration.EnvironmentConfiguration; | |||
import org.apache.commons.configuration.MapConfiguration; | |||
import org.apache.commons.configuration.SystemConfiguration; | |||
import org.apache.commons.configuration.*; | |||
import org.apache.commons.io.IOUtils; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; |
@@ -18,7 +18,7 @@ | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.batch; | |||
package org.sonar.runner.batch; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Lists; | |||
@@ -31,7 +31,6 @@ import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.api.batch.bootstrap.ProjectDefinition; | |||
import org.sonar.runner.RunnerException; | |||
import org.sonar.runner.utils.SonarRunnerUtils; | |||
import java.io.File; | |||
import java.io.FileFilter; |
@@ -17,7 +17,7 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.utils; | |||
package org.sonar.runner.batch; | |||
import org.apache.commons.lang.StringUtils; | |||
@@ -34,9 +34,9 @@ public final class SonarRunnerUtils { | |||
/** | |||
* Transforms a comma-separated list String property in to a array of trimmed strings. | |||
* | |||
* | |||
* This works even if they are separated by whitespace characters (space char, EOL, ...) | |||
* | |||
* | |||
*/ | |||
public static String[] getListFromProperty(Properties properties, String key) { | |||
return StringUtils.stripAll(StringUtils.split(properties.getProperty(key, ""), ',')); |
@@ -21,4 +21,4 @@ | |||
* Internal package that creates the project definition and launches the analyses based on it. | |||
* Should not be used by consumers. | |||
*/ | |||
package org.sonar.runner.internal.batch; | |||
package org.sonar.runner.batch; |
@@ -1,50 +0,0 @@ | |||
/* | |||
* Sonar Standalone Runner | |||
* Copyright (C) 2011 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper; | |||
/** | |||
* Exception thrown by the bootstrapper when something bad happens. | |||
*/ | |||
public class BootstrapException extends RuntimeException { | |||
private static final long serialVersionUID = -4974995497654796971L; | |||
/** | |||
* See {@link RuntimeException} | |||
*/ | |||
public BootstrapException(String message) { | |||
super(message); | |||
} | |||
/** | |||
* See {@link RuntimeException} | |||
*/ | |||
public BootstrapException(Throwable cause) { | |||
super(cause); | |||
} | |||
/** | |||
* See {@link RuntimeException} | |||
*/ | |||
public BootstrapException(String message, Throwable cause) { | |||
super(message, cause); | |||
} | |||
} |
@@ -1,24 +0,0 @@ | |||
/* | |||
* Sonar Standalone Runner | |||
* Copyright (C) 2011 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
/** | |||
* Internal package that provides API to bootstrap Sonar Batch. | |||
* Should not be used by consumers. | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper; |
@@ -1,24 +0,0 @@ | |||
/* | |||
* Sonar Standalone Runner | |||
* Copyright (C) 2011 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
/** | |||
* Internal package that provides utils for internal purposes. | |||
* Should not be used by consumers. | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper.utils; |
@@ -1,23 +0,0 @@ | |||
/* | |||
* Sonar Standalone Runner | |||
* Copyright (C) 2011 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
/** | |||
* Public package that provides utils and can be used by consumers. | |||
*/ | |||
package org.sonar.runner.utils; |
@@ -17,9 +17,7 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper; | |||
import org.sonar.runner.internal.bootstrapper.BootstrapClassLoader; | |||
package org.sonar.runner; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
@@ -33,14 +31,16 @@ public class BootstrapClassLoaderTest { | |||
public ExpectedException thrown = ExpectedException.none(); | |||
@Test | |||
public void shouldRestrictLoadingFromParent() throws Exception { | |||
BootstrapClassLoader classLoader = new BootstrapClassLoader(getClass().getClassLoader(), "org.sonar.ant"); | |||
assertThat(classLoader.canLoadFromParent("org.sonar.ant.Launcher")).isTrue(); | |||
public void should_restrict_loading_from_parent() throws Exception { | |||
BootstrapClassLoader classLoader = new BootstrapClassLoader(getClass().getClassLoader(), "org.apache.ant"); | |||
assertThat(classLoader.canLoadFromParent("org.sonar.runner.batch.Launcher")).isFalse(); | |||
assertThat(classLoader.canLoadFromParent("org.sonar.runner.Runner")).isTrue(); | |||
assertThat(classLoader.canLoadFromParent("org.objectweb.asm.ClassVisitor")).isFalse(); | |||
assertThat(classLoader.canLoadFromParent("org.apache.ant.project.Project")).isTrue(); | |||
} | |||
@Test | |||
public void use_isolated_system_classloader_when_parent_is_excluded() throws ClassNotFoundException { | |||
public void should_use_isolated_system_classloader_when_parent_is_excluded() throws ClassNotFoundException { | |||
thrown.expect(ClassNotFoundException.class); | |||
thrown.expectMessage("org.junit.Test"); | |||
ClassLoader parent = getClass().getClassLoader(); | |||
@@ -52,7 +52,7 @@ public class BootstrapClassLoaderTest { | |||
} | |||
@Test | |||
public void find_in_parent_when_matches_unmasked_packages() throws ClassNotFoundException { | |||
public void should_find_in_parent_when_matches_unmasked_packages() throws ClassNotFoundException { | |||
ClassLoader parent = getClass().getClassLoader(); | |||
BootstrapClassLoader classLoader = new BootstrapClassLoader(parent, "org.junit"); | |||
@@ -17,9 +17,9 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.bootstrapper; | |||
package org.sonar.runner; | |||
import org.sonar.runner.internal.bootstrapper.Bootstrapper; | |||
import org.sonar.runner.Bootstrapper; | |||
import org.junit.Test; | |||
@@ -19,9 +19,6 @@ | |||
*/ | |||
package org.sonar.runner; | |||
import org.sonar.runner.internal.bootstrapper.BootstrapException; | |||
import org.sonar.runner.internal.bootstrapper.Bootstrapper; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
@@ -149,8 +146,8 @@ public class RunnerTest { | |||
// but fails with older versions | |||
when(bootstrapper.getServerVersion()).thenReturn("2.1"); | |||
thrown.expect(BootstrapException.class); | |||
thrown.expectMessage("Sonar 2.1 does not support Standalone Runner. Please upgrade Sonar to version 2.11 or more."); | |||
thrown.expect(RunnerException.class); | |||
thrown.expectMessage("Sonar 2.1 is not supported. Please upgrade Sonar to version 2.11 or more."); | |||
runner.checkSonarVersion(bootstrapper); | |||
} | |||
@@ -17,17 +17,18 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.utils; | |||
package org.sonar.runner; | |||
import org.junit.Test; | |||
import org.sonar.runner.Version; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class SonarRunnerVersionTest { | |||
public class VersionTest { | |||
@Test | |||
public void shouldLoadVersion() { | |||
String version = SonarRunnerVersion.getVersion(); | |||
String version = Version.getVersion(); | |||
assertThat(version).contains("."); | |||
assertThat(version).doesNotContain("$"); | |||
} |
@@ -17,7 +17,7 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.batch; | |||
package org.sonar.runner.batch; | |||
import com.google.common.collect.Lists; | |||
import org.apache.commons.configuration.BaseConfiguration; |
@@ -17,7 +17,7 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.internal.batch; | |||
package org.sonar.runner.batch; | |||
import org.junit.Rule; | |||
import org.junit.Test; |
@@ -17,14 +17,13 @@ | |||
* License along with this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.utils; | |||
package org.sonar.runner.batch; | |||
import org.apache.commons.io.IOUtils; | |||
import org.junit.Test; | |||
import org.sonar.test.TestUtils; | |||
import java.io.FileInputStream; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.util.Properties; | |||
@@ -48,7 +47,7 @@ public class SonarRunnerUtilsTest { | |||
assertThat(SonarRunnerUtils.getListFromProperty(props, "prop")).containsOnly("foo", "bar", "toto", "tutu"); | |||
} | |||
private Properties loadPropsFromFile(String filePath) throws FileNotFoundException, IOException { | |||
private Properties loadPropsFromFile(String filePath) throws IOException { | |||
Properties props = new Properties(); | |||
FileInputStream fileInputStream = null; | |||
try { |