<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Helion-Prime Solutions blog &#187; java</title>
	<atom:link href="http://blogs.helion-prime.com/tag/java/feed" rel="self" type="application/rss+xml" />
	<link>http://blogs.helion-prime.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 26 Aug 2010 13:02:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>On-the-fly compilation in Java6</title>
		<link>http://blogs.helion-prime.com/2008/06/13/on-the-fly-compilation-in-java6.html</link>
		<comments>http://blogs.helion-prime.com/2008/06/13/on-the-fly-compilation-in-java6.html#comments</comments>
		<pubDate>Fri, 13 Jun 2008 09:03:05 +0000</pubDate>
		<dc:creator>henadiy.atroshko</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://blogs.helion-prime.com/?p=30</guid>
		<description><![CDATA[One of interesting novelty of Java6 is a possibility to access compiler via special API.
Let&#8217;s look on this feature a bit closer.
In order to have an access to compilation subsystem we should use classes located at javax.tools package [http://java.sun.com/javase/6/docs/api/javax/tools/package-summary.html].
In the future in this package possibly appear classes to work with different external utilities, but at [...]]]></description>
			<content:encoded><![CDATA[<p>One of interesting novelty of Java6 is a possibility to access compiler via special API.<br />
Let&#8217;s look on this feature a bit closer.</p>
<p>In order to have an access to compilation subsystem we should use classes located at javax.tools package [<a href="http://java.sun.com/javase/6/docs/api/javax/tools/package-summary.html">http://java.sun.com/javase/6/docs/api/javax/tools/package-summary.html</a>].<br />
In the future in this package possibly appear classes to work with different external utilities, but at this moment we have only access to the compiler.</p>
<p>As simple example let&#8217;s look on request to compile:</p>
<div class="codecolorer-container java5 mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="java5 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;JavaCompiler compiler = ToolProvider.<span style="color: #006633;">getSystemJavaCompiler</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;Iterable<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>SimpleJavaFileObject<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> srcList = &nbsp;<span style="color: #003399; font-weight: bold;">Arrays</span>.<span style="color: #006633;">asList</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> SimpleJavaFileObject<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">new</span> SimpleJavaFileObject<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">URI</span>.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;string:///myclass.java&quot;</span><span style="color: #009900;">&#41;</span>, Kind.<span style="color: #006633;">SOURCE</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;@<span style="color: #003399; font-weight: bold;">Override</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">CharSequence</span> getCharContent<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">boolean</span> ignoreEncodingErrors<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;class myclass {}&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;JavaFileManager fileManager = compiler.<span style="color: #006633;">getStandardFileManager</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;compiler.<span style="color: #006633;">getTask</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">null</span>, fileManager, <span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span>, srcList<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">call</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p><strong>Let&#8217;s try to understand how it&#8217;s work:</strong></p>
<p>The compiler access input data not directly but via objects inherited form JavaFileObject. Therefore depending on needs of developer information for compilation can be received from any place: network, file, memory; for that we need to implement successor of JavaFileObject.<br />
It is better to do it by inheriting class-gag SimpleJavaFileObject</p>
<p>In our example implementation of SimpleJavaFileObject  returns source of class as constant string. It is slightly harder with output data. There is another abstraction layer called JavaFileManager that is object factory per se.</p>
<p>Standard file manager that we receive in our example let us work with files on the disk. If you need to place output data on the network on in the memory you need to override  JavaFileManager. It is better to do it inheriting ForwardingJavaFileManager, this class retarget request to provided during creation file manager. At the same time you can handle only those request that you need.</p>
<p>Last string of example creates compilation command and execute it at once. As a result of execution we have file in the execution directory of example with name  myclass.class that contains bytecode of appropriate class. It is noteworthy that classloaders of system know nothing about existence of given class and so call Class.forName(“myclass”) throws ClassNotFoundException. </p>
<p>Let&#8217;s complete our example to get class bytecode as byte array. For that we need to implement our own file manager:</p>
<div class="codecolorer-container java5 mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br /></div></td><td><div class="java5 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> JavaMemFileManager <span style="color: #000000; font-weight: bold;">extends</span> ForwardingJavaFileManager <span style="color: #009900;">&#123;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">class</span> ClassMemFileObject <span style="color: #000000; font-weight: bold;">extends</span> SimpleJavaFileObject <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399; font-weight: bold;">ByteArrayOutputStream</span> os = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">ByteArrayOutputStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; ClassMemFileObject<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> className<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">URI</span>.<span style="color: #006633;">create</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;mem:///&quot;</span> + className + Kind.<span style="color: #006633;">CLASS</span>.<span style="color: #006633;">extension</span><span style="color: #009900;">&#41;</span>, Kind.<span style="color: #006633;">CLASS</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getBytes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">return</span> os.<span style="color: #006633;">toByteArray</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; @<span style="color: #003399; font-weight: bold;">Override</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">OutputStream</span> openOutputStream<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399; font-weight: bold;">IOException</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">return</span> os<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">private</span> HashMap<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String, ClassMemFileObject<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> classes =<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">new</span> HashMap<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>String, ClassMemFileObject<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">public</span> JavaMemFileManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">super</span><span style="color: #009900;">&#40;</span>ToolProvider.<span style="color: #006633;">getSystemJavaCompiler</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getStandardFileManager</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp;@<span style="color: #003399; font-weight: bold;">Override</span><br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">public</span> JavaFileObject getJavaFileForOutput<span style="color: #009900;">&#40;</span>Location location,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #003399; font-weight: bold;">String</span> className, Kind kind, FileObject sibling<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399; font-weight: bold;">IOException</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>StandardLocation.<span style="color: #006633;">CLASS_OUTPUT</span> == location <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> JavaFileObject.<span style="color: #006633;">Kind</span>.<span style="color: #006633;">CLASS</span> == kind<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ClassMemFileObject clazz = <span style="color: #000000; font-weight: bold;">new</span> ClassMemFileObject<span style="color: #009900;">&#40;</span>className<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;classes.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>className, clazz<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">return</span> clazz<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; &nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">getJavaFileForOutput</span><span style="color: #009900;">&#40;</span>location, className, kind, sibling<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> getClassBytes<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> className<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; &nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>classes.<span style="color: #006633;">containsKey</span><span style="color: #009900;">&#40;</span>className<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">return</span> classes.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>className<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getBytes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #006600; font-weight: bold;">null</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>As you see our file manager override method  getJavaFileForOutput that complier calls to receive output file object. Here we check destination, for new classes it should be StandardLocation.CLASS_OUTPUT and type. If it correspond to newly compiled class then we create new file object: we save it and pass it to the compiler.<br />
Then we can receive access to the bytecode with method getClassBytes(className) passing the name of the class.</p>
<p>Let us change previous example to use new functionality:</p>
<div class="codecolorer-container java5 mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="java5 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;....<br />
&nbsp; &nbsp;<span style="color: #006633;">JavaFileManager</span> fileManager = <span style="color: #000000; font-weight: bold;">new</span> JavaMemFileManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;compiler.<span style="color: #006633;">getTask</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">null</span>, fileManager, <span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span>, <span style="color: #006600; font-weight: bold;">null</span>, srcList<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">call</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> myClassBytes = <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>JavaMemFileManager<span style="color: #009900;">&#41;</span>fileManager<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getClassBytes</span><span style="color: #009900;">&#40;</span>“myclass”<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;....</div></td></tr></tbody></table></div>
<p>And yet one feature of example execution in our case will be absence of file on the disk.</p>
<p>Finally I made a library that makes easier access to Java6 Compiler API.<br />
See details on: [ <a href="http://opensource.helion-prime.com/jruntime/">http://opensource.helion-prime.com/jruntime/</a> ]</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.helion-prime.com/2008/06/13/on-the-fly-compilation-in-java6.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
