Support finding tools.jar from other locations as well

This commit is contained in:
Roel Spilker committed 2009-12-07 15:54:46 +01:00
1 parent 26e0b7559e
commit 021c9a223c
2 files changed
+96 -81

No files matched your search

+7 -1
View File
@@ -35,6 +35,8 @@ import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.List;
import javax.tools.JavaFileObject;
import lombok.delombok.CommentPreservingParser.ParseResult;
import com.zwitserloot.cmdreader.CmdReader;
@@ -248,10 +250,14 @@ public class Delombok {
in.close();
}
}
public void delombok(JavaFileObject file, Writer writer) throws IOException {
ParseResult result = parser.parse(file, force);
result.print(writer);
}
public void delombok(String file, Writer writer) throws IOException {
ParseResult result = parser.parse(file, force);
result.print(writer);
}
+89 -80
View File
@@ -25,90 +25,13 @@ public class DelombokApp implements LombokApp {
runDirectly(args);
return 0;
} catch (ClassNotFoundException e) {
//tools.jar is probably not on the classpath. We're going to try and find it, and then load the rest via a ClassLoader that includes tools.jar.
final File toolsJar = findToolsJar();
if (toolsJar == null) {
Class<?> delombokClass = loadDelombok();
if (delombokClass == null) {
System.err.println("Can't find tools.jar. Rerun delombok with tools.jar on the classpath.");
return 1;
}
final JarFile toolsJarFile = new JarFile(toolsJar);
ClassLoader loader = new ClassLoader() {
private Class<?>loadStreamAsClass(String name, boolean resolve, InputStream in) throws ClassNotFoundException {
try {
try {
byte[] b = new byte[65536];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
in.close();
byte[] data = out.toByteArray();
Class<?> c = defineClass(name, data, 0, data.length);
if (resolve) resolveClass(c);
return c;
} finally {
in.close();
}
} catch (IOException e2) {
throw new ClassNotFoundException(name, e2);
}
}
@Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
String rawName = name.replace(".", "/") + ".class";
JarEntry entry = toolsJarFile.getJarEntry(rawName);
if (entry == null) {
if (name.startsWith("lombok.")) return loadStreamAsClass(name, resolve, super.getResourceAsStream(rawName));
return super.loadClass(name, resolve);
}
try {
return loadStreamAsClass(name, resolve, toolsJarFile.getInputStream(entry));
} catch (IOException e2) {
throw new ClassNotFoundException(name, e2);
}
}
@Override public URL getResource(String name) {
JarEntry entry = toolsJarFile.getJarEntry(name);
if (entry == null) return super.getResource(name);
try {
return new URL("jar:file:" + toolsJar.getAbsolutePath() + "!" + name);
} catch (MalformedURLException ignore) {
return null;
}
}
@Override public Enumeration<URL> getResources(final String name) throws IOException {
JarEntry entry = toolsJarFile.getJarEntry(name);
final Enumeration<URL> parent = super.getResources(name);
if (entry == null) return super.getResources(name);
return new Enumeration<URL>() {
private boolean first = false;
@Override public boolean hasMoreElements() {
return !first || parent.hasMoreElements();
}
@Override public URL nextElement() {
if (!first) {
first = true;
try {
return new URL("jar:file:" + toolsJar.getAbsolutePath() + "!" + name);
} catch (MalformedURLException ignore) {
return parent.nextElement();
}
}
return parent.nextElement();
}
};
}
};
try {
loader.loadClass("lombok.delombok.Delombok").getMethod("main", String[].class).invoke(null, new Object[] {args.toArray(new String[0])});
loadDelombok().getMethod("main", String[].class).invoke(null, new Object[] {args.toArray(new String[0])});
} catch (InvocationTargetException e1) {
Throwable t = e1.getCause();
if (t instanceof Error) throw (Error)t;
@@ -119,6 +42,92 @@ public class DelombokApp implements LombokApp {
}
}
public static Class<?> loadDelombok() throws Exception {
//tools.jar is probably not on the classpath. We're going to try and find it, and then load the rest via a ClassLoader that includes tools.jar.
final File toolsJar = findToolsJar();
if (toolsJar == null) {
System.err.println("Can't find tools.jar. Rerun delombok with tools.jar on the classpath.");
return null;
}
final JarFile toolsJarFile = new JarFile(toolsJar);
ClassLoader loader = new ClassLoader() {
private Class<?>loadStreamAsClass(String name, boolean resolve, InputStream in) throws ClassNotFoundException {
try {
try {
byte[] b = new byte[65536];
ByteArrayOutputStream out = new ByteArrayOutputStream();
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
in.close();
byte[] data = out.toByteArray();
Class<?> c = defineClass(name, data, 0, data.length);
if (resolve) resolveClass(c);
return c;
} finally {
in.close();
}
} catch (IOException e2) {
throw new ClassNotFoundException(name, e2);
}
}
@Override protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
String rawName = name.replace(".", "/") + ".class";
JarEntry entry = toolsJarFile.getJarEntry(rawName);
if (entry == null) {
if (name.startsWith("lombok.")) return loadStreamAsClass(name, resolve, super.getResourceAsStream(rawName));
return super.loadClass(name, resolve);
}
try {
return loadStreamAsClass(name, resolve, toolsJarFile.getInputStream(entry));
} catch (IOException e2) {
throw new ClassNotFoundException(name, e2);
}
}
@Override public URL getResource(String name) {
JarEntry entry = toolsJarFile.getJarEntry(name);
if (entry == null) return super.getResource(name);
try {
return new URL("jar:file:" + toolsJar.getAbsolutePath() + "!" + name);
} catch (MalformedURLException ignore) {
return null;
}
}
@Override public Enumeration<URL> getResources(final String name) throws IOException {
JarEntry entry = toolsJarFile.getJarEntry(name);
final Enumeration<URL> parent = super.getResources(name);
if (entry == null) return super.getResources(name);
return new Enumeration<URL>() {
private boolean first = false;
@Override public boolean hasMoreElements() {
return !first || parent.hasMoreElements();
}
@Override public URL nextElement() {
if (!first) {
first = true;
try {
return new URL("jar:file:" + toolsJar.getAbsolutePath() + "!" + name);
} catch (MalformedURLException ignore) {
return parent.nextElement();
}
}
return parent.nextElement();
}
};
}
};
return loader.loadClass("lombok.delombok.Delombok");
}
private void runDirectly(List<String> args) {
Delombok.main(args.toArray(new String[0]));
}