improved handling of manifest only classpaths

This commit is contained in:
Timo Westkämper 2012-06-16 17:56:01 +03:00
parent 1b777cdaa7
commit 2630c8a42d
6 changed files with 126 additions and 16 deletions

View File

@ -4,13 +4,13 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.mysema.codegen</groupId>
<artifactId>codegen</artifactId>
<version>0.4.11</version>
<version>0.5.0</version>
<name>Codegen</name>
<description>Code generation and compilation for Java</description>
<parent>
<groupId>com.mysema.home</groupId>
<artifactId>mysema-source</artifactId>
<version>0.2.0</version>
<version>0.2.2</version>
</parent>
<packaging>jar</packaging>

View File

@ -6,6 +6,7 @@
package com.mysema.codegen;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
@ -18,6 +19,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.jar.Manifest;
import javax.lang.model.SourceVersion;
import javax.tools.DiagnosticListener;
@ -27,6 +29,8 @@ import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import com.google.common.base.Joiner;
/**
* SimpleCompiler provides a convenience wrapper of the JavaCompiler interface
* with automatic classpath generation
@ -36,19 +40,33 @@ import javax.tools.ToolProvider;
*/
public class SimpleCompiler implements JavaCompiler {
public static String getClassPath(URLClassLoader classLoader) {
private static final Joiner pathJoiner = Joiner.on(File.pathSeparator);
public static String getClassPath(URLClassLoader cl) {
try {
StringBuilder path = new StringBuilder();
for (URL url : ((URLClassLoader) classLoader).getURLs()) {
if (path.length() > 0) {
path.append(File.pathSeparator);
List<String> paths = new ArrayList<String>();
if (cl.getURLs().length == 1 && cl.getURLs()[0].getPath().contains("surefirebooter")) {
// extract MANIFEST.MF Class-Path entry, since the Java Compiler doesn't handle
// manifest only jars in the classpath correctly
URL url = cl.findResource("META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(url.openStream());
String classpath = (String) manifest.getMainAttributes().getValue("Class-Path");
for (String entry : classpath.split(" ")) {
URL entryUrl = new URL(entry);
String decodedPath = URLDecoder.decode(entryUrl.getPath(), "UTF-8");
paths.add(new File(decodedPath).getAbsolutePath());
}
String decodedPath = URLDecoder.decode(url.getPath(), "UTF-8");
path.append(new File(decodedPath).getAbsolutePath());
}
return path.toString();
} else {
for (URL url : cl.getURLs()) {
String decodedPath = URLDecoder.decode(url.getPath(), "UTF-8");
paths.add(new File(decodedPath).getAbsolutePath());
}
}
return pathJoiner.join(paths);
} catch (UnsupportedEncodingException e) {
throw new CodegenException(e);
} catch (IOException e) {
throw new CodegenException(e);
}
}
@ -119,6 +137,7 @@ public class SimpleCompiler implements JavaCompiler {
for (String arg : arguments) {
args.add(arg);
}
System.err.println(args);
return compiler.run(in, out, err, args.toArray(new String[args.size()]));
}

View File

@ -0,0 +1,26 @@
package com.mysema.codegen;
import com.google.common.base.CaseFormat;
public final class StringUtils {
public static String capitalize(String str) {
return CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, str);
}
public static String uncapitalize(String str) {
return CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, str);
}
public static String escapeJava(String str) {
str = str.replace("\\", "\\\\");
str = str.replace("\"", "\\\"");
str = str.replace("\r", "\\\r");
str = str.replace("\t", "\\\t");
str = str.replace("\n", "\\\n");
return str;
}
private StringUtils() {}
}

View File

@ -6,6 +6,7 @@
package com.mysema.codegen;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.StringWriter;
@ -24,9 +25,10 @@ public class AnnotationTest {
@Test
public void ClassAnnotation() throws IOException {
writer.annotation(getClass().getAnnotation(Annotation.class));
assertEquals(
"@com.mysema.codegen.Annotation(clazz=com.mysema.codegen.AnnotationTest.class, prop2=false)",
w.toString().trim());
String option1 = "@com.mysema.codegen.Annotation(clazz=com.mysema.codegen.AnnotationTest.class, prop2=false)";
String option2 = "@com.mysema.codegen.Annotation(prop2=false, clazz=com.mysema.codegen.AnnotationTest.class)";
String serialized = w.toString().trim();
assertTrue(serialized.equals(option1) || serialized.equals(option2));
}
@Test

View File

@ -6,14 +6,21 @@
package com.mysema.codegen;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import junit.framework.Assert;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Test;
public class SimpleCompilerTest {
@ -24,13 +31,43 @@ public class SimpleCompilerTest {
}
@Test
public void Run() {
@Ignore
public void Run() throws UnsupportedEncodingException {
new File("target/out").mkdir();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
URLClassLoader classLoader = (URLClassLoader)Thread.currentThread().getContextClassLoader();
// create classpath
StringBuilder path = new StringBuilder();
for (URL url : ((URLClassLoader) classLoader).getURLs()) {
if (path.length() > 0) {
path.append(File.pathSeparator);
}
String decodedPath = URLDecoder.decode(url.getPath(), "UTF-8");
path.append(new File(decodedPath).getAbsolutePath());
}
System.err.println(path);
// compile
List<String> options = Arrays.asList(
"-classpath", path.toString(),
"-s", "target/out",
"src/test/java/com/mysema/codegen/SimpleCompilerTest.java");
int compilationResult = compiler.run(null, null, null,
options.toArray(new String[options.size()]));
if (compilationResult != 0) {
Assert.fail("Compilation Failed");
}
}
@Test
public void Run2() {
new File("target/out2").mkdir();
JavaCompiler compiler = new SimpleCompiler();
System.out.println(compiler.getClass().getName());
List<String> options = new ArrayList<String>(3);
options.add("-s");
options.add("target/out");
options.add("target/out2");
options.add("src/test/java/com/mysema/codegen/SimpleCompilerTest.java");
int compilationResult = compiler.run(null, null, null,
options.toArray(new String[options.size()]));
@ -38,5 +75,6 @@ public class SimpleCompilerTest {
Assert.fail("Compilation Failed");
}
}
}

View File

@ -0,0 +1,25 @@
package com.mysema.codegen;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.Manifest;
import org.junit.Test;
public class SurefireBooterTest {
@Test
public void test() throws IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader instanceof URLClassLoader) {
URLClassLoader cl = (URLClassLoader) classLoader;
if (cl.getURLs().length == 1 && cl.getURLs()[0].getPath().contains("surefirebooter")) {
URL url = cl.findResource("META-INF/MANIFEST.MF");
Manifest manifest = new Manifest(url.openStream());
System.out.println(manifest.getMainAttributes().getValue("Class-Path"));
}
}
}
}