Using sun javac to parse java source

A

Alex J

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.

P.S.:
Looks like it is possible to use internal AST representation by
casting base code model classes in the annotation processor:

@Override
public void init(ProcessingEnvironment procEnv) {
super.init(procEnv);
this.javacProcessingEnv = (JavacProcessingEnvironment) procEnv;
this.maker = TreeMaker.instance(javacProcessingEnv.getContext());
....
}

@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
if (annotations == null || annotations.isEmpty()) {
return false;
}

final Elements elements = javacProcessingEnv.getElementUtils();
 
A

Arne Vajhøj

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.

Arne
 
L

Lew

L

Lew

Arne said:
Sure, but it is still a complex API.

Yes, it is. That isn't a reason not to know it, if you need that functionality.

Pardon my confusion, but aren't we both recommending the same API? Are yousuggesting that they not know this API now?

Perhaps you misunderstand me to suggest that by "know the API" I do not mean to study the finer points of how to use it?

Could anyone infer that by pointing to the first step on the road to knowledge that I mean they should sit on the curb at the beginning and go no further?

Or perhaps you believe that after pointing the OP to the beginning of that journey I should do all the research for them, and Google on their behalf for all the further reading that they should do, or even read it for them and feed it predigested to them like a mommy-bird feeding her pre-fledgling babies?

I see nothing in my earlier post to suggest that it is not a complex API, or that they should stop at the first indicated signpost.

The value of the link to the API is that it shows some basic information, and given a certain level of programming experience or commitment or both itcan lead them into study and experimentation that will solve their problem.. It indicates that the API is, indeed, standard, and gives hope that there is a solution. There has been no assertion that competence with the API ends with reading the Javadocs.
 
S

Sebastian

Am 24.08.2011 01:00, schrieb Arne Vajhøj:
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.

Arne
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.

-- Sebastian
 
A

Arne Vajhøj

Am 24.08.2011 01:00, schrieb Arne Vajhøj:
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);
}
}
 
A

Arne Vajhøj

Yes, it is. That isn't a reason not to know it, if you need that functionality.

Pardon my confusion, but aren't we both recommending the same API? Are you suggesting that they not know this API now?

Perhaps you misunderstand me to suggest that by "know the API" I do not mean to study the finer points of how to use it?

Could anyone infer that by pointing to the first step on the road to knowledge that I mean they should sit on the curb at the beginning and go no further?

Or perhaps you believe that after pointing the OP to the beginning of that journey I should do all the research for them, and Google on their behalf for all the further reading that they should do, or even read it for them and feed it predigested to them like a mommy-bird feeding her pre-fledgling babies?

I see nothing in my earlier post to suggest that it is not a complex API, or that they should stop at the first indicated signpost.

The value of the link to the API is that it shows some basic information, and given a certain level of programming experience or commitment or both it can lead them into study and experimentation that will solve their problem. It indicates that the API is, indeed, standard, and gives hope that there is a solution. There has been no assertion that competence with the API ends with reading the Javadocs.

There is this usenet tradition that comments relates to what is
is written below.

So when you talk about studying the API below my statement about it
being a complex API, then I assume that it relates to that.

Arne
 
L

Lew

Arne said:
There is this usenet tradition that comments relates to what is
is written below.

So when you talk about studying the API below my statement about it
being a complex API, then I assume that it relates to that.

It did relate to that. It gave a starting point to study the complex API. "Relate to" != "contradict".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top