From 2630c8a42d2434515d3929bdf8c2b6dd622500d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Sat, 16 Jun 2012 17:56:01 +0300 Subject: [PATCH] improved handling of manifest only classpaths --- pom.xml | 4 +- .../com/mysema/codegen/SimpleCompiler.java | 37 ++++++++++++---- .../java/com/mysema/codegen/StringUtils.java | 26 ++++++++++++ .../com/mysema/codegen/AnnotationTest.java | 8 ++-- .../mysema/codegen/SimpleCompilerTest.java | 42 ++++++++++++++++++- .../mysema/codegen/SurefireBooterTest.java | 25 +++++++++++ 6 files changed, 126 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/mysema/codegen/StringUtils.java create mode 100644 src/test/java/com/mysema/codegen/SurefireBooterTest.java diff --git a/pom.xml b/pom.xml index 743763a0c..c3f879339 100644 --- a/pom.xml +++ b/pom.xml @@ -4,13 +4,13 @@ 4.0.0 com.mysema.codegen codegen - 0.4.11 + 0.5.0 Codegen Code generation and compilation for Java com.mysema.home mysema-source - 0.2.0 + 0.2.2 jar diff --git a/src/main/java/com/mysema/codegen/SimpleCompiler.java b/src/main/java/com/mysema/codegen/SimpleCompiler.java index 4b47cb30f..9239d5a88 100644 --- a/src/main/java/com/mysema/codegen/SimpleCompiler.java +++ b/src/main/java/com/mysema/codegen/SimpleCompiler.java @@ -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 paths = new ArrayList(); + 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()])); } diff --git a/src/main/java/com/mysema/codegen/StringUtils.java b/src/main/java/com/mysema/codegen/StringUtils.java new file mode 100644 index 000000000..47a0ccae2 --- /dev/null +++ b/src/main/java/com/mysema/codegen/StringUtils.java @@ -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() {} + +} diff --git a/src/test/java/com/mysema/codegen/AnnotationTest.java b/src/test/java/com/mysema/codegen/AnnotationTest.java index 6cdf58df4..96a763a93 100644 --- a/src/test/java/com/mysema/codegen/AnnotationTest.java +++ b/src/test/java/com/mysema/codegen/AnnotationTest.java @@ -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 diff --git a/src/test/java/com/mysema/codegen/SimpleCompilerTest.java b/src/test/java/com/mysema/codegen/SimpleCompilerTest.java index f1433d02e..fa0fc4f6a 100644 --- a/src/test/java/com/mysema/codegen/SimpleCompilerTest.java +++ b/src/test/java/com/mysema/codegen/SimpleCompilerTest.java @@ -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 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 options = new ArrayList(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"); } } + } diff --git a/src/test/java/com/mysema/codegen/SurefireBooterTest.java b/src/test/java/com/mysema/codegen/SurefireBooterTest.java new file mode 100644 index 000000000..64240559b --- /dev/null +++ b/src/test/java/com/mysema/codegen/SurefireBooterTest.java @@ -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")); + } + } + } + +}