package org.sonar.runner.api;
import org.apache.commons.io.FileUtils;
+import org.sonar.runner.impl.Logs;
import java.io.File;
}
FileUtils.deleteQuietly(workDir);
runner.setProperty(RunnerProperties.WORK_DIR, workDir.getAbsolutePath());
+ Logs.info("Work directory: " + workDir.getAbsolutePath());
}
/**
@Test
public void testUsedJavaExe() throws Exception {
+ System.out.println(System.getProperty("java.io.tmpdir"));
File javaExe = new Os().thisJavaExe();
assertThat(javaExe).isNotNull().isFile().exists();
assertThat(javaExe.getName()).contains("java");
*
* @since 1.5
*/
-public final class ProjectReactorBuilder {
+class ProjectReactorBuilder {
private static final Logger LOG = LoggerFactory.getLogger(ProjectReactorBuilder.class);
private Properties properties;
private File rootProjectWorkDir;
- public ProjectReactorBuilder(Properties properties) {
+ ProjectReactorBuilder(Properties properties) {
this.properties = properties;
}
- public ProjectReactor build() {
+ ProjectReactor build() {
ProjectDefinition rootProject = defineProject(properties, null);
rootProjectWorkDir = rootProject.getWorkDir();
defineChildren(rootProject);
* This works even if they are separated by whitespace characters (space char, EOL, ...)
*
*/
- public static String[] getListFromProperty(Properties properties, String key) {
+ static String[] getListFromProperty(Properties properties, String key) {
return StringUtils.stripAll(StringUtils.split(properties.getProperty(key, ""), ','));
}
Logs.info("Error stacktraces are turned on.");
}
runnerFactory.create(conf.properties()).execute();
- // Logs.info("Work directory: " + runner.getWorkDir().getCanonicalPath());
} catch (Exception e) {
displayExecutionResult(stats, "FAILURE");
public class BatchLauncher {
final String isolatedLauncherClass;
+ private final TempCleaning tempCleaning;
/**
* For unit tests
*/
- BatchLauncher(String isolatedLauncherClass) {
+ BatchLauncher(String isolatedLauncherClass, TempCleaning tempCleaning) {
this.isolatedLauncherClass = isolatedLauncherClass;
+ this.tempCleaning = tempCleaning;
}
public BatchLauncher() {
- this.isolatedLauncherClass = "org.sonar.runner.batch.IsolatedLauncher";
+ this("org.sonar.runner.batch.IsolatedLauncher", new TempCleaning());
}
public void execute(Properties props, List<Object> extensions) {
}
/**
- * @return the {@link IsolatedLauncher} instance for unit tests
+ * @return the {@link org.sonar.runner.batch.IsolatedLauncher} instance for unit tests
*/
Object doExecute(final JarDownloader jarDownloader, final Properties props, final List<Object> extensions) {
Object launcher = AccessController.doPrivileged(new PrivilegedAction<Object>() {
String unmaskedPackages = props.getProperty(InternalProperties.RUNNER_UNMASKED_PACKAGES, "");
IsolatedClassloader classloader = new IsolatedClassloader(getClass().getClassLoader(), unmaskedPackages.split(":"));
classloader.addFiles(jarFiles);
- return delegateExecution(classloader, props, extensions);
+ Object launcher = delegateExecution(classloader, props, extensions);
+ tempCleaning.clean();
+ return launcher;
}
private Object delegateExecution(IsolatedClassloader classloader, Properties properties, List<Object> extensions) {
--- /dev/null
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.filefilter.AgeFileFilter;
+import org.apache.commons.io.filefilter.AndFileFilter;
+import org.apache.commons.io.filefilter.PrefixFileFilter;
+
+import java.io.File;
+import java.util.Collection;
+
+/**
+ * The file sonar-runner-batch.jar is locked by the classloader on Windows and can't be dropped at the end of the execution.
+ * See {@link BatchLauncher}
+ */
+class TempCleaning {
+ static final int ONE_DAY_IN_MILLISECONDS = 24 * 60 * 60 * 1000;
+
+ final File tempDir;
+
+ TempCleaning() {
+ this(new File(System.getProperty("java.io.tmpdir")));
+ }
+
+ /**
+ * For unit tests
+ */
+ TempCleaning(File tempDir) {
+ this.tempDir = tempDir;
+ }
+
+ void clean() {
+ long cutoff = System.currentTimeMillis() - ONE_DAY_IN_MILLISECONDS;
+ Collection<File> files = FileUtils.listFiles(tempDir, new AndFileFilter(
+ new PrefixFileFilter("sonar-runner-batch"),
+ new AgeFileFilter(cutoff)
+ ), null);
+
+ for (File file : files) {
+ FileUtils.deleteQuietly(file);
+ }
+ }
+}
@Test
public void should_download_jars_and_execute_batch() {
- BatchLauncher launcher = new BatchLauncher(FakeIsolatedLauncher.class.getName());
+ TempCleaning tempCleaning = mock(TempCleaning.class);
+ BatchLauncher launcher = new BatchLauncher(FakeIsolatedLauncher.class.getName(), tempCleaning);
Properties props = new Properties();
props.put("foo", "bar");
assertThat(isolatedLauncher.props.get("foo")).isEqualTo("bar");
assertThat(isolatedLauncher.extensions).isSameAs(extensions);
verify(jarDownloader).download();
+ verify(tempCleaning).clean();
}
@Test
public void should_use_isolated_classloader() {
- BatchLauncher launcher = new BatchLauncher(FakeIsolatedLauncher.class.getName());
+ BatchLauncher launcher = new BatchLauncher(FakeIsolatedLauncher.class.getName(), mock(TempCleaning.class));
Properties props = new Properties();
// The current classloader in not available -> fail to load FakeIsolatedLauncher
--- /dev/null
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class TempCleaningTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void should_clean_jvm_tmp_dir( ){
+ TempCleaning cleaning = new TempCleaning();
+ assertThat(cleaning.tempDir).isDirectory().exists();
+ }
+
+ @Test
+ public void should_clean() throws Exception {
+ File dir = temp.newFolder();
+ File oldBatch = new File(dir, "sonar-runner-batch656.jar");
+ FileUtils.write(oldBatch, "foo");
+ oldBatch.setLastModified(System.currentTimeMillis() - 3 * TempCleaning.ONE_DAY_IN_MILLISECONDS);
+
+ File youngBatch = new File(dir, "sonar-runner-batch123.jar");
+ FileUtils.write(youngBatch, "foo");
+
+ File doNotDelete = new File(dir, "jacoco.txt");
+ FileUtils.write(doNotDelete, "foo");
+
+ assertThat(oldBatch).exists();
+ assertThat(youngBatch).exists();
+ assertThat(doNotDelete).exists();
+ new TempCleaning(dir).clean();
+
+ assertThat(oldBatch).doesNotExist();
+ assertThat(youngBatch).exists();
+ assertThat(doNotDelete).exists();
+ }
+}