Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #7357
| Date | 2011-08-24 19:19 -0400 |
|---|---|
| From | Arne Vajhøj <arne@vajhoej.dk> |
| Newsgroups | comp.lang.java.programmer |
| Subject | Re: Using sun javac to parse java source |
| References | <66227810-c927-4197-a138-f25b54f26f7f@k8g2000yqk.googlegroups.com> <4e543134$0$305$14726298@news.sunsite.dk> <j32e2d$jgg$1@news.albasani.net> |
| Message-ID | <4e55871c$0$309$14726298@news.sunsite.dk> (permalink) |
| Organization | SunSITE.dk - Supporting Open source |
On 8/24/2011 4:51 AM, Sebastian wrote:
> Am 24.08.2011 01:00, schrieb Arne Vajhøj:
>> On 8/23/2011 4:24 PM, Alex J wrote:
>>> I'm curious whether it is possible to use JavacParser -
>>> http://docjar.org/docs/api/com/sun/tools/javac/parser/JavacParser.html
>>> - built-in to OpenJDK to parse standalone java files (though claimed
>>> to be "internal use only API"). I googled but I've found no answers.
>>
>> Java 1.6 and newer contains a supported callable Java compiler.
>>
>> Use that.
>>
>> If you only want to syntax check you will need to discard the
>> generated byte code in case of success, but that is easy.
>>
>> The API is a bit complex many would say over engineered, but
>> it works fine.
> You might find a detailed example useful. There is an article
> about "Dynamic Code Generation with Java Compiler API in Java 6"
> by Swaminathan Bhaskar at
>
> http://www.scribd.com/doc/56642760/Java-Compiler
>
> The article shows how to compile source from strings to byte arrays.
I have a slightly differentexample - see below.
Arne
====
package test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
public class JC {
public static void dynamicCall(String clznam, String src, String
cp, String metnam) throws Exception {
SpecialClassLoader xcl = new SpecialClassLoader();
compileMemoryMemory(src, cp, clznam, xcl, System.err);
Class<?> c = Class.forName(clznam, true, xcl);
Object o = c.newInstance();
c.getMethod(metnam, new Class[] { }).invoke(o, new Object[] { });
}
public static void compileMemoryMemory(String src, String cp,
String name, SpecialClassLoader xcl, PrintStream err) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diacol = new
DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager sjfm =
javac.getStandardFileManager(diacol, null, null);
SpecialJavaFileManager xfm = new SpecialJavaFileManager(sjfm, xcl);
CompilationTask compile = javac.getTask(null, xfm, diacol,
Arrays.asList(new String[] { "-classpath", cp }), null,
Arrays.asList(new
JavaFileObject[] { new MemorySource(name, src) }));
boolean status = compile.call();
if(err != null) {
err.println("Compile status: " + status);
for(Diagnostic<? extends JavaFileObject> dia :
diacol.getDiagnostics()) {
err.println(dia);
}
}
}
}
class MemorySource extends SimpleJavaFileObject {
private String src;
public MemorySource(String name, String src) {
super(URI.create("string:///" + name.replace(".", "/") +
".java"), Kind.SOURCE);
this.src = src;
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return src;
}
public OutputStream openOutputStream() {
throw new IllegalStateException();
}
public InputStream openInputStream() {
return new ByteArrayInputStream(src.getBytes());
}
}
class MemoryByteCode extends SimpleJavaFileObject {
private ByteArrayOutputStream baos;
public MemoryByteCode(String name) {
super(URI.create("byte:///" + name.replace(".", "/") +
".class"), Kind.CLASS);
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
throw new IllegalStateException();
}
public OutputStream openOutputStream() {
baos = new ByteArrayOutputStream();
return baos;
}
public InputStream openInputStream() {
throw new IllegalStateException();
}
public byte[] getBytes() {
return baos.toByteArray();
}
}
class SpecialJavaFileManager extends
ForwardingJavaFileManager<StandardJavaFileManager> {
private SpecialClassLoader xcl;
public SpecialJavaFileManager(StandardJavaFileManager sjfm,
SpecialClassLoader xcl) {
super(sjfm);
this.xcl = xcl;
}
public JavaFileObject getJavaFileForOutput(Location location,
String name, JavaFileObject.Kind kind, FileObject sibling) throws
IOException {
name = sibling.getName().substring(1,
sibling.getName().length() - 5).replace("/", ".");
MemoryByteCode mbc = new MemoryByteCode(name);
xcl.addClass(name, mbc);
return mbc;
}
}
class SpecialClassLoader extends ClassLoader {
private Map<String,MemoryByteCode> m;
public SpecialClassLoader() {
super(SpecialClassLoader.class.getClassLoader());
m = new HashMap<String, MemoryByteCode>();
}
protected Class<?> findClass(String name) throws
ClassNotFoundException {
MemoryByteCode mbc = m.get(name);
if(mbc != null) {
return defineClass(name, mbc.getBytes(), 0,
mbc.getBytes().length);
} else {
throw new ClassNotFoundException(name);
}
}
public void addClass(String name, MemoryByteCode mbc) {
m.put(name, mbc);
}
}
Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Find similar
Using sun javac to parse java source Alex J <vstrength@gmail.com> - 2011-08-23 13:24 -0700
Re: Using sun javac to parse java source Arne Vajhøj <arne@vajhoej.dk> - 2011-08-23 19:00 -0400
Re: Using sun javac to parse java source Lew <lewbloch@gmail.com> - 2011-08-23 17:25 -0700
Re: Using sun javac to parse java source Arne Vajhøj <arne@vajhoej.dk> - 2011-08-23 21:52 -0400
Re: Using sun javac to parse java source Lew <lewbloch@gmail.com> - 2011-08-23 20:20 -0700
Re: Using sun javac to parse java source Arne Vajhøj <arne@vajhoej.dk> - 2011-08-24 19:22 -0400
Re: Using sun javac to parse java source Lew <lewbloch@gmail.com> - 2011-08-24 21:05 -0700
Re: Using sun javac to parse java source Sebastian <sebastian@undisclosed.invalid> - 2011-08-24 10:51 +0200
Re: Using sun javac to parse java source Arne Vajhøj <arne@vajhoej.dk> - 2011-08-24 19:19 -0400
csiph-web