Only jars manifest support in Java Compiler API

Does the Java compiler support only jar files with manifests with Class-Path in classpath arguments?

I am trying to use the Java Compiler API in Maven Surefire tests, but it seems that the Java Compiler API, or rather ToolProvider.getSystemJavaCompiler() , is not processing the Surefire manifest banks properly.

Here is a piece of code that shows a failed test

  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"); } 
+4
source share
1 answer

I had a similar problem with launching a built-in jetty with jsp compilation inside surefire unit tests. A simpler solution was to configure the surefire plugin so as not to use a manifest jar

  <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <useManifestOnlyJar>false</useManifestOnlyJar> </configuration> </plugin> 

A more complicated solution was to extend the class path to include jar files referenced by the manifest fields of the declaration class of the class

 static List<String> getClassPathForJspCompiler() throws IOException { List<String> classPath = Lists.newArrayList(System.getProperty("java.class.path") .split(File.pathSeparator)); return expandManifestClassPathElements(classPath); } private static List<String> expandManifestClassPathElements(List<String> classPath) throws IOException { for (int i = 0; i < classPath.size(); i++) { String element = classPath.get(i); if (element.endsWith(".jar")) { for (String manifestElement : getManifestClassPath(element)) { // add to the end of the class path so it will get processed if (!classPath.contains(manifestElement)) { // only add if not already present to prevent cyclic loop classPath.add(manifestElement); } } } } return classPath; } private static List<String> getManifestClassPath(String jarFilePath) throws IOException { File jarFile = new File(jarFilePath); if (!jarFile.isFile()) { return ImmutableList.of(); } Manifest manifest = new JarFile(jarFile).getManifest(); if (manifest == null) { return ImmutableList.of(); } String manifestClassPath = manifest.getMainAttributes().getValue( Attributes.Name.CLASS_PATH); if (manifestClassPath == null) { return ImmutableList.of(); } // split at all spaces that are not preceded by a backslash return Lists.newArrayList(manifestClassPath.split("(?<!\\\\) ")); } 
+2
source

All Articles