The Source for Java Technology Collaboration

Home » java.net Forums » JDK » Java SE Snapshots: Project Feedback

Thread: Using the Compiler API (JSR 199)

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 7 - Last Post: Jun 3, 2006 11:14 AM by: vvaldo
vvaldo

Posts: 5
Using the Compiler API (JSR 199)
Posted: May 29, 2006 10:03 AM
  Click to reply to this thread Reply

I am trying to use the Compiler API (JSR 199) but fail to get it working.

According to the JavaDoc on java.lang.Compiler:

When the Java Virtual Machine first starts, it determines if the system property java.compiler exists.
... If so, it is assumed to be the name of a library ... the loadLibrary method in class System is called to load that library.

I checked this and
System.out.println(System.getProperty("java.compiler"));
returns null.

To which values should it be set?

alexlamsl

Posts: 343
Re: Using the Compiler API (JSR 199)
Posted: May 29, 2006 12:15 PM   in response to: vvaldo
  Click to reply to this thread Reply

Hmmm.... what you are quoting and saying has been there even in J2SE 1.4.2

So I hope you won't mind me asking - which version of JDK are you using?

alexlamsl

Posts: 343
Re: Using the Compiler API (JSR 199)
Posted: May 29, 2006 12:16 PM   in response to: vvaldo
  Click to reply to this thread Reply

And just FYI, the JSR 199 stuff will appear in the javax.compiler package

vvaldo

Posts: 5
Re: Using the Compiler API (JSR 199)
Posted: May 30, 2006 3:40 AM   in response to: alexlamsl
  Click to reply to this thread Reply

I am using build 85 (25 May) of Mustang.

Well, I started with the method getSystemJavaCompilerTool() in the class javax.tools.ToolProvider. Which returned null...
Browsing the API docs lead me to java.lang.Compiler class that writes about the property "java.compiler".
So I assumed that I have to set the System property "java.compiler" to something like "com.sun.tools.javac". But that doesn't help, still get null from getSystemJavaCompilerTool.

The JSR 199 comes with some sample code that I am unable to compile (draft???).

I want to try out the Compiler API in Java 6 by writing a small Swing program that compiles Java sourcecode from a JTextArea into a class and runs it.

So i need more information on how to use this new Mustang functionality.

alexlamsl

Posts: 343
Re: Using the Compiler API (JSR 199)
Posted: May 30, 2006 3:55 AM   in response to: vvaldo
  Click to reply to this thread Reply

I think you need to include lib/tools.jar which contains the Compiler API classes.

terifan

Posts: 6
Re: Using the Compiler API (JSR 199)
Posted: May 31, 2006 8:39 AM   in response to: vvaldo
  Click to reply to this thread Reply

The compiler is actually located in javax.tools package.

This is a really uggly sample that functions with Java 6 beta. Note that the class need to change name since the JVM caches classes. There used to be methods to circumvent that feature by using custommade classloaders but I havn't been able to get that to work. So in this sample, the class changes name...

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import javax.tools.*;
 
 
public class Test15
{
	public static void main(String ... args)
	{
		try
		{
			String name = "HelloWorld1";
			String source = "public class HelloWorld1 implements MainClass{public void print(){System.out.println(\"hello world\");}}";
 
			MainClass instance = compile(name, source);
 
			instance.print();
 
			name = "HelloWorld2";
			source = "public class HelloWorld2 implements MainClass{public void print(){System.out.println(\"HELLO WORLD\");}}";
 
			instance = compile(name, source);
 
			instance.print();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
 
	private static MainClass compile(String aName, final String aSource) throws Exception
	{
		FileOutputStream out = new FileOutputStream(aName + ".java");
		out.write(aSource.getBytes());
		out.close();
 
		SimpleJavaFileObject sourceFile = new SimpleJavaFileObject(aName, JavaFileObject.Kind.SOURCE)
		{
			public CharSequence getCharContent(boolean b) throws IOException
			{
				return aSource;
			}
			public InputStream openInputStream() throws IOException
			{
				return new ByteArrayInputStream(aSource.getBytes());
			}
			public OutputStream openOutputStream() throws IOException
			{
				throw new RuntimeException();
			}
		};
 
		JavaCompilerTool tool = ToolProvider.defaultJavaCompiler();
 
		tool.setOutputDirectory(new File("d:/java/src"));
 
		JavaCompilerTool.CompilationTask task = tool.run(null, sourceFile);
		task.run();
 
		if (!task.getResult())
		{
			for (DiagnosticMessage msg : task.getDiagnostics())
			{
				System.out.println(msg);
			}
		
			System.exit(-1);
		}
 
		Class clazz = Test15.class.getClassLoader().loadClass(aName);
		MainClass instance = (MainClass)clazz.newInstance();
 
		return instance;
	}
}
 
interface MainClass
{
	public void print();
}


terifan

Posts: 6
Re: Using the Compiler API (JSR 199)
Posted: Jun 1, 2006 2:35 AM   in response to: terifan
  Click to reply to this thread Reply

Here's a revised version using the API from the latest build (B85).

import java.io.*;
import javax.tools.*;
 
 
public class Test15
{
	public static void main(String ... args)
	{
		try
		{
			String name = "HelloWorld1";
			String source = "public class HelloWorld1 implements MainClass{public void print(){System.out.println(\"hello world\");}}";
 
			MainClass instance = compile(name, source);
 
			instance.print();
 
			name = "HelloWorld2";
			source = "public class HelloWorld2 implements MainClass{public void print(){System.out.println(\"HELLO WORLD\");}}";
 
			instance = compile(name, source);
 
			instance.print();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
 
	private static MainClass compile(String aName, final String aSource) throws Exception
	{
		FileOutputStream out = new FileOutputStream(aName + ".java");
		out.write(aSource.getBytes());
		out.close();
 
		File [] files1 = new File[]{new File(aName + ".java")};
 
		JavaCompilerTool compiler = ToolProvider.getSystemJavaCompilerTool();
		DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
		StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics);
 
		Iterable<? extends JavaFileObject> compilationUnits1 = fileManager.getJavaFileObjectsFromFiles(java.util.Arrays.asList(files1));
		compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits1).run();
 
		for (Diagnostic diagnostic : diagnostics.getDiagnostics())
		{
			System.out.println(diagnostic);
		}
 
		fileManager.close();
 
		Class clazz = ClassLoader.getSystemClassLoader().loadClass(aName);
		MainClass instance = (MainClass)clazz.newInstance();
 
		return instance;
	}
}
 
interface MainClass
{
	public void print();
}


vvaldo

Posts: 5
Re: Using the Compiler API (JSR 199)
Posted: Jun 3, 2006 11:14 AM   in response to: vvaldo
  Click to reply to this thread Reply

Got it running, using the lastest build 86, but getting runtime error:

HelloWorld1.java:1: cannot find symbol
symbol: class MainClass
java.lang.ClassNotFoundException: HelloWorld1
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at nljug.demo.compiler.Test.compile(Test.java:56)
at nljug.demo.compiler.Test.main(Test.java:18)




 XML java.net RSS