<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Osvaldo Pinali Doederlein&apos;s Blog</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/" />
<modified>2008-06-15T17:17:16Z</modified>
<tagline></tagline>
<id>tag:weblogs.java.net,2008:/blog/opinali/232</id>
<generator url="http://www.movabletype.org/" version="3.01D">Movable Type</generator>
<copyright>Copyright (c) 2008, opinali</copyright>
<entry>
<title>New Java 7 language features should be backwards compatible</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2008/01/new_java_7_lang_1.html" />
<modified>2008-06-15T17:17:16Z</modified>
<issued>2008-01-14T12:40:14Z</issued>
<id>tag:weblogs.java.net,2008:/blog/opinali/232.8857</id>
<created>2008-01-14T12:40:14Z</created>
<summary type="text/plain">The discussion about new language features in Java SE 7 is on again, with abundant feedback to JavaPolis presentations on closures and several &quot;little&quot; language features (like improved generic type inference, catch clauses, String switch, typedef and others). I am a supporter of the current closures proposal, but no matter which of these features you like, there&apos;s one aspect I see no one discussing: compatibility with older JVMs...</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>
<dc:subject>JSR</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>
Right NOW, I am just starting to use J2SE 5.0's features, like generic types or java.util.concurrent, in my bigger projects. The reason is that large corps are slow, and they use application servers from even slower vendors... As a project architect, I'd love to send an email to my clients today, informing that our projects are moving to Java SE 6 and Glassfish V2 (or other up-to-date server) next week - we'll even do that migration for free!! because my life will become much better afterwards... but no, this is obviously not an option.
</p>
<p>
So that's the real world: I'm just starting to use Java 5. Java 6 is a distant dream - IBM's JDK 6 just went gold after an year-long beta, but there is no WebSphere update yet to include the new JDK, I guess I'll have to wait another 1-2 years until this update is fully complete, supported, tested, endorsed, and available in my clients' production servers. So when it comes to Java 7, well, I think I'll be happy if I can use that in large-scale, mission-critical applications (with IBM gear anyway), before I retire...
</p>
<p>
The real problem is that Java 5's language features were implemented with too many ties to the J2SE 5.0 platform: -source 5 will only accept -target 5. There's an unsupported javac switch that will allow some generics to target 1.4. But javac could do much better, as proven by third-party tools like RetroWeaver and JBoss Retro. (Similar support from javac would be much simpler than in those tools; javac could generate alternative code for older JVMs straight away, instead of generating 5.0-only bytecode that needs to pass through complex bytecode transformations to be replaced by alterenative code.) But it's also hopeles to use these tools in the environments I deal with. These translators have two severe problems:
</p>
<p>
1) They are not official tools. If I propose to use these things, my client's first question will be "is this supported by [insert large app server vendor here]?".
<br/>
2) They make the edit/compile/deploy/debug cycle even more complex. I have systems with several dozen EARs and over a hundred projects, and I depend on the productivity of IDEs that update deployment into servers, automatically and quickly, and these IDEs have no flexibility to add a bytecode post-processor anywhere (but correct me if I am wrong, it's been some time since I last checked these tools).
</p>
<p>
So, my #1 wish for Java SE 7, whatever is the set of new language features that we decide to implement, is: make a best effort to support these features with -target 5, or at the very least -target 6. All features proposed to date are in the category of syntax sugar that's easily compilable into bytecode that current JVMs can load. Of course there's always some corner casees, like J2SE 5.0's enums which required new serialization support in the guts of the Java core; or in the same release, generics requiring new reflection APIs. So even if the proposals for Java SE 7 require special runtime support, there are several workarounds:
</p>
<p>
- Generating different code for older JVMs, even if it's slower (good solution when the runtime support is only an optimization).
<br/>
- Backporting the new runtime support to the older JVMs, but making it private - for example, repackaging new APIs into sun.* packages, and translating calls to these APIs.
<br/>
- Proving compatibility jars that can be dropped in older JREs' lib/endorsed. BTW, this could also be a great solution for critical new core APIs. See the <a href="http://backport-jsr166.sourceforge.net/">backport-util-concurrent project</a> for a good example - but it shares the same problems of being a non-official, non-supported package (although it's easier to sneak into projects: just drop the jar in your EAR's /lib and don't tell anyone...).
</p>
<p>
]]>

</content>
</entry>
<entry>
<title>Sun&apos;s new syncrhonized security updates policy</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2007/10/suns_new_syncrh.html" />
<modified>2008-01-14T12:18:21Z</modified>
<issued>2007-10-05T18:02:53Z</issued>
<id>tag:weblogs.java.net,2007:/blog/opinali/232.8380</id>
<created>2007-10-05T18:02:53Z</created>
<summary type="text/plain">Beginning with 1.4.2_16 + 1.5.0u13 + 1.6.0u3, Sun is moving to a new policy of releasing synchronized security updates of all supported versions of Java SE.</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>
More details in this article: <a href="http://java.sun.com/developer/technicalArticles/javase/security_adv/">Sun Advances Security for the Java SE Platform</a>. The updates were echoed by some news sites, but not always correctly, for example <a href="http://www.computerworld.com/action/article.do?command=viewArticleBasic&articleId=9040941&source=NLT_PM&nlid=8">Computerworld</a> has no mention to the advancements exposed in Sun's article, plus they get a critical fact wrong stating that "<em>Neither JRE nor Web Start includes an automatic update mechanism; users must manually download and apply the updated versions</em>"... duh!!
</p>
<p>
My $0.02 here is observing that Sun is realizing the fact that Java SE is a major applications platform, so it deserves the same treatment of other platforms. For example on every "Patch Tuesday", Windows Update pushes the latest security fixes for all supported versions of Windows (including all localizations). I think most other OS vendors do the same. Patching each version on different schedules is dangerous because the first patch release provides hackers with substantial new information about the fixed bug... For open-source platforms like Java SE this is even more critical: if you patch version 6 today and other versions only two weeks later, the bad guys will have two weeks to analyze the changes in v6, identifying the exact code that was broken so devising an attack becomes a piece of cake, and "port" this attack to target the unpached versions if necessary.
</p>
<p>
Now the new security policy is much better, kudos to Sun! And the timing couldn't be better, right on the heels of the upcoming Java Kernel / Update N / whatever release. Strong security management is much more critical in that space, since most back-end JREs, those serving Java EE apps, are professionally maintained and behind firewalls so the risk of any security defect is lower than for home users, or even intranet users running JAWS rich-clients.
<p>
]]>

</content>
</entry>
<entry>
<title>Where is my 10GHz CPU???</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2007/10/where_is_my_10g.html" />
<modified>2008-01-14T12:18:57Z</modified>
<issued>2007-10-01T17:35:03Z</issued>
<id>tag:weblogs.java.net,2007:/blog/opinali/232.8344</id>
<created>2007-10-01T17:35:03Z</created>
<summary type="text/plain">I was just re-reading Stephen Hawking&apos;s The Universe in a Nutshell when I read that Intel chips should hit 10GHz by year 20007. Well, here we are in 2007 and where are the double-digit-gigahertz CPUs? :-)</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[I won't rehash everything everybody already knows about the end of the "free lunch" of increasing CPU speeds, just point this curiosity. Being fair on S.H., he was just quoting projections from Intel. This book is from 2001, not such a long time compared to the 3-4 years of design for each CPU generation; so it's funny that Intel wouldn't know better - or perhaps they did, but didn't want to tell us. In the same chapter, Hawking states that future computers would have to be more parallel if they wanted to match our brain's intelligence. IMHO he was an optimist, because we didn't yet make ANY substantial progress towards real understanding of the human mind - and one cannot program in a computer a system that's not understood. But if this situation ever changes (and I'll put serious money that Hawking's search for the Great Unification Theory will end much sooner than that), parallelism will obviously play a major role. But this doesn't matter, even the 2010 version of Notepad will have to be highly concurrent to keep up with the featuritis escalation of our industry. So, grab yourself <a href="http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601">a good book on concurrency</a> if you plan to be worth anything as a programmer when <a href="http://www.intel.com/technology/itj/2007/v11i3/">massively</a> <a href="http://www.azulsystems.com/products/compute_appliance.htm">multicore</a> <a href="http://www.sun.com/processors/niagara/">architectures</a> become mainstream even in the desktop, which won't take many years...]]>

</content>
</entry>
<entry>
<title>No tabs? Yes, you ARE nuts!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2007/09/no_tabs_yes_you.html" />
<modified>2008-01-14T12:20:13Z</modified>
<issued>2007-09-26T18:28:40Z</issued>
<id>tag:weblogs.java.net,2007:/blog/opinali/232.8326</id>
<created>2007-09-26T18:28:40Z</created>
<summary type="text/plain">Kelly O&apos;Hair informs the OpenJDK source repository is about to be cleaned out of tab characters... too bad! Here is a small utility to help programmers who like and know how to use tabs.</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>
<a href="http://weblogs.java.net/blog/kellyohair/archive/2007/09/openjdk_mercuri_3.html">Quote</a>: <strong>(WHAT? NO TABS? ... yes, no tabs ... ARE YOU NUTS? ... at times ... WHY? ... because tabs create a source display problem ... BUT IT WORKS FINE FOR ME IN VI/EMACS! ... yes, but what about everybody else?)</strong>
</p>
<p>
Tabs are only a problem if you mix tabs and spaces before the first non-whitespace char, or indent some lines with tabs and others with spaces, or if you use tabs after the first non-whitespace char. If you have discipline to use tabs the way God intended when He created the ASCII charset; that is, using tabs (and only tabs) for indentation only - then tabs have the advantage of allowing each programmer to pick his or her preferred indentation size, and none of the claimed disadvantages.
</p>
<p>
I have written a small Java utility that will scan a directory tree with text files, and fix tab/whitespace usage automatically. I wrote this utility after searching, and not finding, anything similar on the Internet - it seems there are some utilities (created from programmers from the dark side of the force) that will do the reverse operation of expanding tabs to spaces. I think only Jalopy would do what I wanted, but at the cost of forcing me to run a full reformat.
</p>
<p>
The code is very small, so I'm just including it in this blog; enjoy if you find it useful. It's released to the public domain. The program is easy to use and efficient, and I won't claim that any code is bug-free but I've been using it for a couple years without any issues. I fear however, that this code may be confused by filesystems with links (limitation of java.io), or arbitrary Unicode data (I assume 8-bit chars). And I didn't have time to add really cool features like IDE integrations. Clearly it's not a sufficiently advanced program to make me the next famous open source project leader, so I'm posting this here just to help other programmers who are in the Right side of the Tab Wars... yeah, you know what you're supposed to do now: just wait till all your coworkers go home next Friday night; checkout the entire company repositories' sources; run FixTabs from the root; commit. ;-)
</p>
<p>
<pre>
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.regex.Pattern;

/**
 * Fixes usage of physical tabs in text files: Tabs are mandatory for indentation,
 * and only allowed for that purpose (forbidden after first non-blank in line).
 * 
 * @author osvaldo
 */
public class FixTabs
{
	private static int spacesPerTab = 4;
	private static final ByteArrayOutputStream baos = new ByteArrayOutputStream();
	private static final String[] defaultIncludes = { ".*\\.java", ".*\\.properties" };
	private static final String[] defaultExcludes =
	{
		"\\..*",     // .svn, Unix, Eclipse hidden directories
		"CVS",       // CVS
		"bin",       // Common output directory for Eclipse
		"dist",      // Common output directory for NetBeans
		"build",     // Common output directory for NetBeans
		"nbproject", // Common output directory for NetBeans
		"target",    // Common output directory for Maven
	};

	public static void main (final String[] args)
	{
		if (args.length > 3 ||
				(args.length > 0 && ("-?".equals(args[0]) || "-help".equals(args[1]))))
			help();
		
		final File root = new File(args.length < 1 ? "." : args[0]);
		
		if (args.length >= 2) try
		{
			spacesPerTab = Integer.parseInt(args[1]);
		}
		catch (NumberFormatException e)
		{
			help();
		}
		
		final ArrayList<Pattern> includeList = new ArrayList<Pattern>(); 
		final ArrayList<Pattern> excludeList = new ArrayList<Pattern>(); 

		for (int i = 2; i < args.length; ++i)
		{
			if (args[i].startsWith("+"))
				includeList.add(Pattern.compile(args[i].substring(1)));
			else if (args[i].startsWith("-"))
				excludeList.add(Pattern.compile(args[i].substring(1)));
			else
				help();
		}
		
		if (includeList.isEmpty()) for (final String p: defaultIncludes)
			includeList.add(Pattern.compile(p));
		
		if (excludeList.isEmpty()) for (final String p: defaultExcludes)
			excludeList.add(Pattern.compile(p));

		final int count = fixDirectory(root,
			includeList.toArray(new Pattern[includeList.size()]),
			excludeList.toArray(new Pattern[excludeList.size()]));
		System.out.println("Fixed: " + count);
	}
	
	private static void help ()
	{
		System.out.println(
			"FixTabs [root [spacesPerTab [+includePattern*] [-excludePattern*]]]\n" +
			"Ex.: FixTabs . 4 +.*\\.java +.*\\.properties -CVS");
	}

	/**
	 * Processes a directory recursively.
	 */
	private static int fixDirectory (final File dir, final Pattern[] includeFiles,
		final Pattern[] excludeDirs)
	{
		System.out.print(dir.getAbsolutePath() + " ... ");
		final File[] files = dir.listFiles();
		if (files == null) return 0;
		int count = 0;
		int changed = 0;
		
		for (int i = 0; i < files.length; ++i)
		{
			final File file = files[i];
			
			if (file.canRead() && file.canWrite() && !file.isHidden() &&
					matchesAny(includeFiles, file.getAbsolutePath()))
			{
				if (fixFile(file)) ++changed;
				++count;
			}
		}
		
		System.out.println(Integer.toString(changed) + '/' + count);
		
		for (int i = 0; i < files.length; ++i)
		{
			final File file = files[i];
			
			if (file.isDirectory() && !matchesAny(excludeDirs, file.getName()))
				changed += fixDirectory(file, includeFiles, excludeDirs);
		}
		
		return changed;
	}

	/**
	 * Checks a string against a set of patterns; returns true if any pattern matches.
	 */
	private static boolean matchesAny (final Pattern[] patterns, final String s)
	{
		for (Pattern p: patterns)
			if (p.matcher(s).matches())
				return true;
		
		return false;
	}

	/**
	 * Processes a single file.
	 * 
	 * @param file The file to process.
	 * @return <code>true</code> if file was touched; otherwise, it was already okay.
	 */
	private static boolean fixFile (final File file)
	{
		RandomAccessFile raf = null;
		
		try
		{
			raf = new RandomAccessFile(file, "rw");
			final byte[] originalData = new byte[(int)raf.length()];
			raf.readFully(originalData);
			final byte[] fixedData = fix(originalData);
			if (fixedData == null) return false;
			raf.seek(0);
			raf.write(fixedData);
			raf.setLength(fixedData.length);
			raf.close();
			return true;
		}
		catch (IOException e)
		{
			System.err.println(e);
			return false;
		}
		finally
		{
			if (raf != null) try { raf.close(); } catch (IOException e) {}
		}
	}

	/**
	 * Fixes tabs & spaces, if needed.
	 * 
	 * @param data Original data in ASCII format (1 byte = 1 char).
	 * @return Fixed data, or null if no fix was necessary.
	 */
	private static byte[] fix (final byte[] data)
	{
		baos.reset();
		boolean changed = false;
		boolean indenting = true;
		int position = 0;
		
		for (int read = 0; read < data.length; ++read)
		{
			final byte c = data[read];
			
			if (c == '\n')
			{
				indenting = true;
				position = 0;
				baos.write(c);
			}
			else if (c == '\r')
				baos.write(c);
			else if (indenting)
			{
				if (c == ' ')
				{
					if (++position % spacesPerTab == 0)
					{
						changed = true;
						baos.write('\t');
					}
				}
				else if (c == '\t')
				{
					baos.write(c);
					position += (spacesPerTab - position % spacesPerTab);
				}
				else
				{
					for (int i = 0; i < position % spacesPerTab; ++i)
						baos.write(' ');
					
					baos.write(c);
					indenting = false;
					++position;
				}
			}
			else
			{
				if (c == '\t')
				{
					changed = true;
					
					do
					{
						baos.write(' ');
					}
					while (++position % spacesPerTab != 0);
				}
				else
				{
					baos.write(c);
					++position;
				}
			}
		}
		
		if (indenting) for (int i = 0; i < position % spacesPerTab; ++i)
			baos.write(' ');

		return changed ? baos.toByteArray() : null;
	}
}
</pre>
</p>]]>

</content>
</entry>
<entry>
<title>Sun JDK 6.0u2 is available</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2007/07/sun_jdk_60u2_is.html" />
<modified>2008-01-14T12:21:10Z</modified>
<issued>2007-07-04T19:08:29Z</issued>
<id>tag:weblogs.java.net,2007:/blog/opinali/232.7791</id>
<created>2007-07-04T19:08:29Z</created>
<summary type="text/plain">Sun JDK 6.0 Update 2 is available.</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>
This is a massive update with <a href="http://java.sun.com/javase/6/webnotes/ReleaseNotes.html">182 fixes and enhancements</a>,
including a few performance optimizations that allowed Sun to recover the SPECjbb2005 nonclustered record as reported by
<a href="http://blogs.sun.com/dagastine/entry/new_specjbb2005_world_record">David Dagastine</a>. Perhaps due to this many changes, Update2 took some time to be delivered (David's perf report dates from JavaOne, two full months behind us) so it seems like Sun took the extra time to make this a very stable update too.
</p>
<p>
I particularly like fix
<a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6523674">6523674: Allow different styles of java object fields allocation</a>.
This improvement makes HotSpot smarter about laying out the fields of objects with inheritance. Elaborating further on the bugtrack commnents, say you have "class A { int x; byte y; }" and "class B extends A { short z; }". Up to 6.0u1, HotSpot would generate the following layouts (ignoring the object header, and assuming 32-bit platform / 4-byte alignment):
</p>
<p>
<pre>
class A:
--------
0-3:   x
4:     y
5-7:   (padding:3)

class B:
--------
0-3:   x
4:     y
5-7:   (padding:3)
8-9:   z
10-11: (padding:2)
</pre>
</p>
<p>
The new release is better, it uses free space in the superclass layout when possible (e.g. when the derived class has small fields that fit in some "inherited" padding slot):
</p>
<p>
<pre>
class B:
--------
0-3:   x
4:     y
5:     (padding:1)
6-7:   z
</pre>
</p>
<p>
In the example, notice that "z" is a 16-bit field so it only needs to be aligned on a 16-bit boundary. Final result, instances of "B" will be 4 bytes smaller in the new JVM, which makes everything better (allocation/construction time, GC overhead, CPU cache efficiency, locality, etc.). This optimization should be more effective for code with deep inheritance hierarchies, and even better for 64-bit platforms that require 64-bit references and bigger alignment;
for example, "class C { Object o; int i; }" results (again ignoring the header) in a packed 8-byte object for 32 bits, but under a 64-bit JVM it expands to a 16-byte object with 4 bytes of padding after "i" (since "int" is always 32-bit regardless of the JVM), so this padding can now be used for small fields of subclasses - and under a 64-bit JVM, most types become "small" (compared to alignment): everything except references, longs and doubles. In short, if you have a big server app that keeps tons of complex objects in memory (e.g. caches of persistent entities), you may observe some significant improvement with this update. Tell me if you find anything.
</p>
<p>
Other major change is the new packaging of Java DB (née Derby), which is now installed on a separate directory. I like this much better. But the installer created the full "db" directory tree under the JDK installation dir, just without any files - anyone confirm this as a bug? And while I'm at this, Java DB's BAT files for Windows stink. Please give me proper native launchers, just like for all JDK tools. Get rid of those pesky frameworks/VeryLongAndMixedCaseName/bin directories also, I always hated that in Derby, why can't you have a single /bin? And why is full documentation included for Java DB but not for the JDK (I'm not claiming that the docs should be bundled or not -- just that it should be consistent). Java DB is still badly integrated into the JDK, please make it look more like an extension of the JDK and not as some alien project that was just zipped into the JDK installation bundle. Yeah I know Sun has already made the most critical integration work, like testing/validating each release.
But they must walk this extra mile to deliver a better developer experience.
</p>
<p>
Higher in my with list, however, is: please update the installer so the installation of the Java update checker is optional. I hate it, as well as ANY software that (without my explicit consent) installs any kind of preloader, auto-updater, monitor, and other crap that just sucks RAM and "phones home" periodically. This stuff should all be either off by default, or allow the user to switch off in the installer and not after the fact after digging in some configuration tool.
</p>]]>

</content>
</entry>
<entry>
<title>Incredible bug in Intersystems Cache&apos;s EJB code</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2007/06/incredible_bug.html" />
<modified>2008-01-14T12:21:47Z</modified>
<issued>2007-06-28T14:38:12Z</issued>
<id>tag:weblogs.java.net,2007:/blog/opinali/232.7759</id>
<created>2007-06-28T14:38:12Z</created>
<summary type="text/plain">Yesterday I was called by a client to diagnose a 100% CPU usage on an EJB project just about to go production, and what I found is close to unbelievable....</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>
To make the story short: Caché (a pure OODBMS) contains a code generator that produces all code you need to EJB-ize some Java class, a process known as <a href="http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=GCJB_Projection">Projection</a>. The evil part is the code it generates for the Entity Beans's unsetEntityContext() method. These methods contain the following code:
<br>- Nulling out all fields. Ok, this is useless because the entity bean itself is being removed from the container structures, but it's harmless (except for the code bloat).
<br>- <strong>System.gc()</strong>.
</p>
<p>
Now, how STUPID is that? Because of this explicit GC call, performed repeatedly by EVERY SINGLE BEAN, the JVM would freeze with 100% CPU usage for several minutes, when the application server decided to clean up its cache, removing hundreds of expired entity beans.
</p>
<p>
The problem apparently happened only on a setup using JBoss 4.2.0 and Sun JDK 1.5.0_09 but not in another with JBoss 4.0.2 and Sun JDK 1.5.0_11, both with similar (JBoss's factory-standard) JVM settings. It's possible that the JDK contributed to the problem. A forced full-GC shouldn't take a lot of time in a JVM that's mostly idle except for a simple cache reaper, and with 120Mb of used heap out of 512Mb. It was taking 1 full second per GC. I guess the long GC time could have been caused by some of the several GC bugs fixed by JDK 1.5.0_10, but I didn't investigate further. I told the client to add -XX:+DisableExplicitGC to the server launching script.
</p>
<p>
It's been several years now that there is NO reason to invoke System.gc() in Java VMs in normal code, only in very special cases (e.g., I do it a lot in microbenchmarks because I want to start each test cycle with the heap in a similar state). Even management/cleanup features in the core of application servers shouldn't do it (one never knows when a burst of client requests may arrive), let alone application code. Thumbs down to JBoss for not disabling explicit GC by default; and two thumbs down to the J2EE / Java EE specs for not forbidding it in app code, at least I didn't find such rule in the specs.
</p>
<p>
Now, how many thumbs down for Intersystems? I'll have to unwear my shoes and I'll be missing a few thumbs still. This mistake is typical of a Java rookie (and a bad one), it's embarrassing in a product of a respected software company. Your Studio doesn't seem to offer an option to disable generation of the System.gc() calls; I don't know the product and perhaps there is a way, but this "feature" should not exist even as an optional / non-default choice. Just find whoever did this, and <em>fire the idiot</em>. I considered writing this blog in politically correct mode, i.e. "in a certain OODBMS's EJB support..." but I decided to be more explicit because all Caché customers should be warned about this issue, even if it's just potential issue, limited to some JVM builds only. (The JVM has no obligation to respond fast to dumb explicit GC calls, even when a boatload of free space exists; the fact that it happens most of the time, in most JVMs under common configurations, is just a bonus.)
</p>
<p>
One last remark: diagnosing this bug was a piece of cake thanks to the JDK's jstat and jstack tools. The RAS facilities of the JVM often saves my day, it's a top item in my list of "why I use Java instead of X, Y or Z".
</p>]]>

</content>
</entry>
<entry>
<title>JSR 305: Annotations for Software Defect Detection</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2006/08/jsr_305_annotat.html" />
<modified>2008-01-14T12:22:06Z</modified>
<issued>2006-08-29T13:42:55Z</issued>
<id>tag:weblogs.java.net,2006:/blog/opinali/232.5449</id>
<created>2006-08-29T13:42:55Z</created>
<summary type="text/plain">From the new JSR homepage: This JSR will work to develop standard annotations (such as @NonNull) that can be applied to Java programs to assist tools that detect software defects. At long last!</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[If you are like me and you'be been voting on bugs like <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4449383">4449383: Support For 'Design by Contract', beyond "a simple assertion facility"</a> (#2 in the Top RFEs!), or <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4093718">4093718: const - qualifier for methods, parameters and return-value</a> (closed as "will not be fixed"), since the pre-history of Java 1.x, it seems that Java SE 7 may be the answer for many of our wishes. Hey, as if closures were not good enough! :-)]]>

</content>
</entry>
<entry>
<title>Java SE 5.0 Update 8&apos;s cool performance fixes</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2006/08/java_se_50_upda.html" />
<modified>2008-01-14T12:22:33Z</modified>
<issued>2006-08-11T21:17:15Z</issued>
<id>tag:weblogs.java.net,2006:/blog/opinali/232.5332</id>
<created>2006-08-11T21:17:15Z</created>
<summary type="text/plain">Java SE 5.0 Update 8 is available, and it solves important performance bugs.  I analyze (in gory detail) one of these...</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>
<dc:subject>Performance</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>Java SE 5.0 Update 8 is <a href="http://java.sun.com/javase/downloads/index.jsp">available</a>. Besides the traditional few dozens of bugfixes, this release closes a number of important performance bugs in the JIT compiler, GC and runtime. So even if you play more in the conservative side, it's a great time to evaluate and upgrade your Java runtime.
</p><p>
One of the fixed perf bugs is <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4803284">Bug 4803284: Bad performance when HotSpot cannot optimize polymorphic calls</a>, which I reported in January 2003 against JDK 1.4.1. That bug received a partial fix with Tiger-b28, when Sun promised the full solution "in next major release" (Mustang), splitting this to <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5074577">Bug 5074577</a>. There's also a dupe, <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4898726">Bug 4898726: Nonstatic method calls take lot more time than static method calls</a>. Well, it seems Sun kept the promise and these bugs are all fully solved now!
</p><p>
I obviously had to re-run my MethodBench (included in the bug report) to see if the new fix did any difference (as the partial fix already made me happy).  And it does, only for HotSpot Server:
</p><p>
<pre>
JDK 5.0 Update 7:

D:\Java\Bench\Method>java -server -Xbatch MethodHard
*** Testing (Hard) ***
Interf  TPoly   Poly    Virtual Final   Static  Native
<b>35,530</b>  25,682  01,155  01,155  01,146  01,138  259,300

JDK 5.0 Update 8:

D:\Java\Bench\Method>java -server -Xbatch MethodHard
*** Testing (Hard) ***
Interf  TPoly   Poly    Virtual Final   Static  Native
<b>14,754</b>  23,599  01,134  01,130  01,134  01,134  254,700

JDK 6.0 build 94:

D:\Java\Bench\Method>java -server -Xbatch MethodHard
*** Testing (Hard) ***
Interf  TPoly   Poly    Virtual Final   Static  Native
<b>13,711</b>  25,318  01,142  01,146  01,146  01,155  67,980
</pre>
</p><p>
(The Reflection test is very slow in the "Hard" case, and I'm in a hurry now.)
</p><p>
The improvement is in the Interf test (interface calls), where both 5.0u8 and Mustang beat u7 in 14ns vs. 35ns per call. Other tests show only marginal improvements. Well, in a world full of complex frameworks abusing of interfaces, this optimization may be significant.  And this is for a "hard" test where the compiler cannot infer a single concrete type (devirtualization). See the relevant benchmark code:
</p><p>
<pre>
public void bench ()
{
	int calls = operations / 1000;
	// Note: HelperB and HelperD are unrelated classes (don't inherit each other),
	// but both implement the polyHardF() method defined by HelperInterface.
	HelperInterface helper = null, h1 = new HelperB(), h2 = new HelperD();

	for (int i = 0; i < 1000; ++i)
	{
		switch (i / 500)
		{
		// Here, I periodically reassign the helper variable to either HelperB or HelperD,
		// making the call-site below really polymorphic, which kills easy dataflow-based
		// dervirtualization.  Notice also that 50% of all calls will go to each class,
		// so profiling won't let the JIT decide to optimize one case (e.g. helperB) in
		// detriment of the other with a type-check + inlining only for the hot case.
		case 0: helper = h1; break;
		case 1: helper = h2; break;
		}

		for (int j = 0; j < calls; ++j)
			// This is the polymorphic, interface-based, call-site to optimize.
			// The invoked methods perform a trivial operation, but one that
			// cannot be optimized out (it updates a static variable).
			helper.polyHardF(i);
	}
}
</pre>
</p><p>
From the bugtrack comments, it seems that this fix is not specific to interface calls.  It's only an artifact of my benchmark that the limitation of the optimizer was only caught in the MethodHard/Interf test.  But since interface-based calls are by far the hardest ones to optimize (due to multiple inheritance), this is good news for complex OO code overall.
</p><p>
How does HotSpot compile this code, in 5.0u8 and Mustang? I looked at the code (using Mustang's debug build and -XX:+PrintOptoAssembly) and saw that it actually inlines both HelperB's and HelperD's implementations of polyHardF().  It's a strong demonstration of several optimizations combined: the compiler must determine that there are only two possible concrete types for the call-site, and that both deserve inlining... and there's more - let's check the code:
</p><p>
<pre>
# Start of the inner loop: int j = 0...

0d8   B12: #    B13 <- B11  Freq: 15356
0d8     XOR    EBP,EBP
0da

# ...Loop body...

0da   B13: #    B29 B14 <- B12 B18      Loop: B13-B18 stride: not constant  Freq: 30715
0da     MOV    ECX,[ESP + #12]
0de     MOV    EBX,[ECX + #4]
0e1     NullCheck ECX
0e1

# The "payload" code for the inlined methods is here, because both
# implementations of testHardF() are identical = { ++x; } where x is a static int
# (and it's the same x, in a shared superclass).  HotSpot was smart enough to
# merge part of the common code (the read and the increment) and move it up.

0e1   B14: #    B16 B15 <- B13  Freq: 30715
0e1     MOV    ECX,#344
0e6     MOV    EDI,[ECX + precise klass Helper: 0x00a3e2a8:Constant:exact *]
0ec     ADD    EDI,[ESP + #16]

# Guard code: helper instanceof HelperB?

0f0     CMPu   EBX,precise klass HelperB: 0x00a3c3d0:Constant:exact *
0f6     Jne,us B16  P=0.266667 C=-1.000000
0f6

# Inlined code for (the rest of) HelperB.testHardF().

# I don't understand completely the need for this code, but I guess HotSpot
# wants to keep track of stack frames, and/or produce a trap if there is some
# change in the class hierarchy that invalidates the inlining.

0f8   B15: #    B18 <- B14  Freq: 22524.3
0f8     MOV    ECX,[ESP + #12]
0fc     #checkcastPP of ECX
0fc     MOV    [ESP + #12],ECX
100     MOV    EBX,#344

# Here the new value for x is stored -- the read and increment were moved up
# for sharing, but the write must be performed in the right place (I think)
# to not produce illegal behaviors: e.g., if helper is neither HelperB nor HelperD,
# quite possible if it is null (the benchmark code makes difficult to prove the
# never-null property of helper), then a NullPointerException should be raised
# and x should not be updated due to out-of-order code.

105     MOV    [EBX + precise klass Helper: 0x00a3e2a8:Constant:exact *],EDI
10b     JMP,s  B18

# Guard code: helper instanceof HelperD?

10b
10d   B16: #    B26 B17 <- B14  Freq: 8190.66
10d     CMPu   EBX,precise klass HelperD: 0x00a3c438:Constant:exact *
113     Jne,us B26  P=0.000001 C=-1.000000
113

# Inlined code for (the rest of) HelperD.testHardF().
# Same stuff as before.  It's sad that, both methods being exactly identical,
# HotSpot inlines and merges only part of their bodies, but doesn't do it
# neither for this bookkeeping code nor for the store.  Quite likely HS doesn't
# want that, so it doesn't lose the ability to walk stacks precisely, in events
# like GC, OSR, and exception stack-trace filling (don't you hate JVMs that don't
# report exact line numbers for all frames, in compiled code?).

115   B17: #    B18 <- B16  Freq: 8190.65
115     MOV    ECX,[ESP + #12]
119     #checkcastPP of ECX
119     MOV    [ESP + #12],ECX
11d     MOV    EBX,#344
122     MOV    [EBX + precise klass Helper: 0x00a3e2a8:Constant:exact *],EDI
122

# ...End of the inner loop: ++j; go back if j < calls

128   B18: #    B13 B19 <- B15 B17 B27  Freq: 30715
128     INC    EBP
129     CMP    EBP,[ESP + #0]
12c     Jlt,s  B13  P=0.999935 C=15360.000000
</pre>
</p><p>
That's it. But just so you don't think the optimizer is now perfect, it could be even better, if HS could combine the switch statement with versioning of the inner loop, so the overhead of testing helper's concrete type and branching to the correct inlined code would be reduced to 1/500th, like this:
<pre>
switch (i / 500)
{
case 0:
	helper = h1;
	for (int j = 0; j < calls; ++j)
		helper.polyHardF(i);
	break;
case 1:
	helper = h2;
	for (int j = 0; j < calls; ++j)
		helper.polyHardF(i);
}
</pre>
</p><p>
This transformation would even dispense the complex optimizations we just saw, because in the new code, there are two call-sites that are trivially identified as non-polymorphic, so the compiler is free to inline with zero overhead, and also do other tricks like replacing the entire loop by "x += 500", thus delivering a >500X boost (in this case, my microbenchmark would be declared "broken" as such code pattern hardly occurs in real app code). But the above optimization is really, really difficult; there is no optimizer (for Java at least) that can do it. Which allows me to conclude with two of my favorite clichés:
<br/>a) There's room for the next major release to be even faster.
<br/>b) Human Assembly hackers (with enough time in their hands) will always win.
</p><p>
Enjoy the new JDK's performance. I haven't yet tried it on real-world application benchmarks, but there are other important perf bugfixes, like <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6298694">Bug 6298694: bad performance with big object in heap</a>, probably much more important than my "pet bug" discussed here, because the latter can screw up with concurrent GC performance.
</p>]]>

</content>
</entry>
<entry>
<title>Mustang&apos;s HotSpot Client gets 58% faster!</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2005/11/mustangs_hotspo.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-11-10T17:13:26Z</issued>
<id>tag:weblogs.java.net,2005:/blog/opinali/232.3604</id>
<created>2005-11-10T17:13:26Z</created>
<summary type="text/plain">Build 59 of Mustang just added a great improvement in the Client VM, for the benefit of all non-server-side Java applications out there.</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<span style="font-weight: bold; font-style: italic;">[FIXED: I
originally posted wrong data for JSE 6.0 Client b59's: the average
score was correct, so it stands that the Client VM became 58% faster;
but scores for the individual tests were identical to other VM as I
copy&amp;pasted the HTML but didn't change the values. Sorry for the
confusion. (I re-checked all other numbers.) Also, I deleted the
comments about an apparently&nbsp; big impact on array-intensive code,
because with the new detailed data, this trend doesn't look so big
anymore, e.g. the FFT test improves more than matmult and LU but it
isn't array-intensive, and SOR is but doesn't improve substantially.]</span><br>
<br>
Mustang is adding new optimizations to HotSpot, not
news, we expect the JVM to learn new tricks at every release. But
the great news is that Sun just added a great performance
enhancement to <span style="font-weight: bold;">HotSpot Client</span>.
Yep, the <span style="font-style: italic;">other</span> HotSpot... the
one that never appears
in benchmarks aimed to make Java or particular JVMs look good.
Unfortunately, you can't
realistically use the Server VM in most client apps, from simple
database
front-ends to action games, as it loads slower, eats
more
RAM, and it's not included in the more ubiquitous JRE package.<br>
<br>
Well, good news: <a href="http://download.java.net/jdk6/binaries/">Build
59</a> includes an improvement recorded as <a
href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6320351">Bug
6320351: new register allocator for C1</a>. ("C1" means
HotSpot Client; C2 is Server.) The bug description is short, so
there it goes in full: "<span style="font-style: italic;">The
existing register allocator for C1 is very primitive and doesn't take
very good advantage of the registers available.&nbsp; It also doesn't
allow values to live across blocks.&nbsp; Along with the high level IR
models locals in such an explicit manner that the code quality for
inlining is fairly bad.</span>" A good <a
href="http://en.wikipedia.org/wiki/Register_allocation">register
allocator</a> is even more important in the Intel x86 platform because
it's got so few architectural registers.<br>
<br>
How cool is this new optimization? I tested with <a
href="http://math.nist.gov/scimark2/">SciMark2</a>, a good benchmark
for that kind of stuff because it runs tight loops of
complex arithmetic expressions, array access and similar operations
that benefit enormously from good register allocation. Results (on
Windows / Pentium-IV 2,25GHz) are:<br>
<br>
<table style="width: 100%; text-align: left;" border="1" cellpadding="2"
cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;"><br>
</td>
<td style="vertical-align: top;">HotSpot Client<br>
</td>
<td style="vertical-align: top;">HotSpot Server<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">J2SE 5.0<br>
Update 5</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">168</span><br>
<table style="width: 100%; text-align: left;" border="1"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">FFT</td>
<td style="vertical-align: top;">87</td>
</tr>
<tr>
<td style="vertical-align: top;">SOR</td>
<td style="vertical-align: top;">308</td>
</tr>
<tr>
<td style="vertical-align: top;">MonteCarlo</td>
<td style="vertical-align: top;">24</td>
</tr>
<tr>
<td style="vertical-align: top;">Sparse matmult</td>
<td style="vertical-align: top;">116</td>
</tr>
<tr>
<td style="vertical-align: top;">LU</td>
<td style="vertical-align: top;">303</td>
</tr>
</tbody>
</table>
</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">410</span><br>
<table style="width: 100%; text-align: left;" border="1"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">FFT</td>
<td style="vertical-align: top;">232</td>
</tr>
<tr>
<td style="vertical-align: top;">SOR</td>
<td style="vertical-align: top;">563</td>
</tr>
<tr>
<td style="vertical-align: top;">MonteCarlo</td>
<td style="vertical-align: top;">70</td>
</tr>
<tr>
<td style="vertical-align: top;">Sparse matmult</td>
<td style="vertical-align: top;">333</td>
</tr>
<tr>
<td style="vertical-align: top;">LU</td>
<td style="vertical-align: top;">853</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td style="vertical-align: top;">JSE 6.0<br>
build 58</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">169</span><br>
<table style="width: 100%; text-align: left;" border="1"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">FFT</td>
<td style="vertical-align: top;">87</td>
</tr>
<tr>
<td style="vertical-align: top;">SOR</td>
<td style="vertical-align: top;">308</td>
</tr>
<tr>
<td style="vertical-align: top;">MonteCarlo</td>
<td style="vertical-align: top;">40</td>
</tr>
<tr>
<td style="vertical-align: top;">Sparse matmult</td>
<td style="vertical-align: top;">119</td>
</tr>
<tr>
<td style="vertical-align: top;">LU</td>
<td style="vertical-align: top;">291</td>
</tr>
</tbody>
</table>
</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">431</span><br>
<table style="width: 100%; text-align: left;" border="1"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">FFT</td>
<td style="vertical-align: top;">274</td>
</tr>
<tr>
<td style="vertical-align: top;">SOR</td>
<td style="vertical-align: top;">560</td>
</tr>
<tr>
<td style="vertical-align: top;">MonteCarlo</td>
<td style="vertical-align: top;">126</td>
</tr>
<tr>
<td style="vertical-align: top;">Sparse matmult</td>
<td style="vertical-align: top;">289</td>
</tr>
<tr>
<td style="vertical-align: top;">LU</td>
<td style="vertical-align: top;">905</td>
</tr>
</tbody>
</table>
</td>
</tr>
<tr>
<td style="vertical-align: top;">JSE 6.0<br>
build 59</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">265</span><br>
<table style="width: 100%; text-align: left;" border="1"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">FFT</td>
<td style="vertical-align: top;">190 (+118%)<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">SOR</td>
<td style="vertical-align: top;">354 (+15%)<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">MonteCarlo</td>
<td style="vertical-align: top;">50 (+25%)<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">Sparse matmult</td>
<td style="vertical-align: top;">250 (+110%)<br>
</td>
</tr>
<tr>
<td style="vertical-align: top;">LU</td>
<td style="vertical-align: top;">480 (65%)<br>
</td>
</tr>
</tbody>
</table>
</td>
<td style="vertical-align: top;"><span style="font-weight: bold;">432</span><br>
<table style="width: 100%; text-align: left;" border="1"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="vertical-align: top;">FFT</td>
<td style="vertical-align: top;">272</td>
</tr>
<tr>
<td style="vertical-align: top;">SOR</td>
<td style="vertical-align: top;">560</td>
</tr>
<tr>
<td style="vertical-align: top;">MonteCarlo</td>
<td style="vertical-align: top;">126</td>
</tr>
<tr>
<td style="vertical-align: top;">Sparse matmult</td>
<td style="vertical-align: top;">289</td>
</tr>
<tr>
<td style="vertical-align: top;">LU</td>
<td style="vertical-align: top;">910</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<br>
Notice the remarkable improvement in HotSpot Client, <span
style="font-weight: bold;">a 58% boost over
5.0</span> (the best stable HotSpot) or Mustang b58 (the previous build
without the new optimization). The
Server VM is also improving in Mustang, but only by a modest 5% over
5.0 (that's already good enough to produce near-ideal code; SciMark2
doesn't need most new tricks of Server
6.0, from <a
href="http://www.ibm.com/developerworks/java/library/j-jtp10185/">lock
coarsening</a> to the [still upcoming] benefits of <a
href="http://www-128.ibm.com/developerworks/java/library/j-jtp09275.html">escape
analysis</a>).<br>
<br>
<span style="font-style: italic; font-weight: bold;"></span>This all
spells good news for Java clients. The improved code
generation is good not just for action
games with sophisticated geometry calculations. Complex algorithms like
Java2D's blt loops, Swing's painting and layout
management code, chart renders, XML parsers, middleware stacks and
others, lie below our vanilla CRUD
&amp; reporting application. HotSpot Client is doomed to always lag
behind Server, but Moore's Law
allows to continuously package more tricks even in the JVM for low-end
machines and user-time sensitive apps.]]>

</content>
</entry>
<entry>
<title>Tomcat goes Native</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2005/10/tomcat_goes_nat.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-10-03T16:53:13Z</issued>
<id>tag:weblogs.java.net,2005:/blog/opinali/232.3367</id>
<created>2005-10-03T16:53:13Z</created>
<summary type="text/plain">The new version of Apache Tomcat will support a library of native code to speend some things up.  Is this the end of the PureJava dogma?</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>

<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>
Check <a href="http://jakarta.apache.org/tomcat/">Tomcat 5.5.12 or later</a>. When you install these new builds, the installer (at least on Windows) offers to download a native code library that Tomcat will use to optimize some performance-critical tasks like connection handling, file I/O and SSL encryption.  This feature is <a href="http://jakarta.apache.org/tomcat/tomcat-5.5-doc/apr.html">documented here</a>.  It looks really cool because it relies on the APR -- Apache Portable Runtime, parte of the Apache HTTP server -- and OpenSSL. Both are very robust, secure and efficient pieces of native code.  And of course, these components are also open source, and very multiplatform (I guess that Apache HTTPD/APR and OpenSSL should support more platforms than J2SE does).  So I don't bother than Tomcat is less "pure" now (do you?).  If you don't want to mess with the additional setup procedures or don't trust this native code, or even if it's not available for your platform (the Tomcat/APR connector is still in alpha stage so it's posible that they don't have pre-built binaries for everybody right now) -- you don't have to use it, it's an optional component.
</p><p>
There are other Java programs and libraries that rely on native libs, but this is indeed very rare in such "standard" components like Tomcat, that is not published by Sun and the JCP but it's very close to such official status. Tomcat is the RI for the Servlets and JSP JSRs, and it's the Web container inside Sun's J2EE server, as well as JBoss and others.  Because Tomcat is so popular -- I don't know any numbers, but I guess it should be the #1 Java Web container either directly or indirectly as piece of larger J2EE products -- this native-code support will eventually propagate to the other servers, products and apps that rely on Tomcat.
</p>
<p>
And of course, there is also <a href="http://weblogs.java.net/blog/jfarcand/archive/2005/06/grizzly_an_http.html">Grizzly</a>, presented in JavaOne 2005; this is an effort to optimize Tomcat with java.nio, part of Sun's <a href="https://glassfish.dev.java.net/">GlassFish</a> project. I wonder whether Grizzly and Tomcat's native connector (which also uses java.nio) are competing or complementary projects? In either case, none of these projects have yet reached production quality, so we'll have to wait for serious benchmarking.
</p>
<p>
The Java VM technology is wonderful, it can very often compensate the overheads imposed by Java's high-level design and beat native compilers, thanks to the opportunities of dynamic optimizations. But there are a few areas where native code is still better, like strong interaction with the OS (e.g. for front-end TCP/IP handling), and "extreme" algorithms like encryption that depend on such tricks as manual vectorization/SIMD (very often you gotta get down to Assembly, because not even stock C compilers are good enough on these). Now that java.nio and DirectBuffers solved most of the Java/native overhead issues, the biggest reasons to not use more native code are portability and robustness. But if you're not writing new libs, just using stuff like the APR that's already mature and multiplatform, I think there's no conflict with the "Run Everywhere" tenet.
</p>]]>

</content>
</entry>
<entry>
<title>Bloated Mustang?</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2005/06/bloated_mustang_1.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-06-22T16:34:20Z</issued>
<id>tag:weblogs.java.net,2005:/blog/opinali/232.2628</id>
<created>2005-06-22T16:34:20Z</created>
<summary type="text/plain">Build
40 of Mustang was the first drop with the first significant
new API additions. And the inevitable happened
as some people started to complain about the addition of &quot;useless&quot;
features:
who needs Web Services, Javascript or an HTTP server? Why Javascript
instead of [put favorite language here]?
Some of these
features are indeed hard to justify in J2SE, if we miss the big picture.</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>
<dc:subject>J2SE</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<a
href="https://mustang.dev.java.net/files/documents/2817/15859/mustang-b40.html">Build
40</a> of Mustang was the first drop with the first significant
new API additions. And the inevitable happened
as some people started to complain about the addition of "useless"
features:
who needs Web Services, Javascript or an HTTP server? Why Javascript
instead of [<span style="font-style: italic;">put favorite language here</span>]?
Some of these
features are indeed hard to justify in J2SE, if we miss the big picture.<br>
<br>
The first (and the biggest) new API is <span style="font-weight: bold;">JAX-WS</span>.
The trend of Web Services has definitely chilled
out from the overhyping of a few years ago; people are not
anymore planning to replace robust and efficient middleware by SOAP
without really good reasons. Nevertheless, WS
are very important, and interoperability was always one hallmark of the
Java platform. Some people even wanted to see basic WS APIs in Tiger,
but
it was too early by then. Now the <a href="http://ws-i.org/">WS-I</a>
specs are more complete and firmly
settled, the implementations of WS-I-compatible runtimes are much
better
than early 2004. So it was not a surprise for me that fewer people
complained about this addition to the core, even though it's the bigger
piece of the cake. This bundling is also important for performance
reasons. The APIs for XML, SOAP and
related technologies are very critical and they can benefit from
important features of newer J2SE releases, from java.nio to
StringBuilder to java.util.concurrent to whatever comes in Mustang. But
non-core APIs (like those in the JWSDP) usually have to keep
compatibility with older J2SEs. So let's put at least all critical
pieces of XML and WS in the core and optimize them to the max, because
the <a
href="http://www.theserverside.net/news/thread.tss?thread_id=34388">pressure</a>
keeps coming.<br>
<br>
Let's see the <span style="font-weight: bold;">HTML
serving</span> feature. I'm frankly
appalled with some people who complained about this,
without making any connection to the Web Services APIs. Hey
folks: SOAP (and the whole WS stack)
requires this. And no, Sun didn't include a full Servlet/JSP/WAR container in Mustang. It's
only the most basic HTTP protocol service capability, and I don't
expect this to be very fat.
Alas, I couldn't seem to find this HTTP serving feature in public APIs,
so I
guess this is internal to the WS packages but I hope it's going to be
exposed by some public API... it costs nothing since the implementation
is already there, people may want to listen HTTP for some non-SOAP
needs, and it's a nice counterpart to the current HTTP capabilities of
the java.net package.<br>
<br>
Now let's talk about <span style="font-weight: bold;">scripting</span>.
Many people like scripting languages, but choosing a <span
style="font-style: italic;">specific </span>language
is a heated debate.&nbsp;
Personally, I don't like these languages; I hate when I have to
hack some Javascript (inevitable in Web GUIs) and that's just how far I
go with scripting. I am a firm believer in static type
checking and
other "bureaucratic" features of conventional languages. On the other
hand, I'm keen on higher-level language features like closures, purer
typesystems, or language-level support for several tasks (collections,
markup languages, SQL etc.). Many scripting languages deliver
these features. I like what I've seen of <a
href="http://groovy.codehaus.org/">Groovy</a> because it's a
higher-level Java
that I'd enjoy to use in some situations – when I don't need the
extra performance of Java's lower-level designs like more static
dispatch and primitive types. But I couldn't care less
about the scripting side of the language: if they drop the interpreter
option or "eval" capabilities, I'll be missing nothing.<br>
<br>
Having presented myself as an independent and unbiased judge (not
a fan of <span style="font-style: italic;">any </span>of the
competing languages), I
think Javascript is a
good choice if any such language is to be embedded in the J2SE.
Javascript may not be the best scripting language
available, either in design or features, but it's
not bad as a pragmatic choice. Javascript is<br>
<ul>
<li>Very popular. Most developers know it already. Billions of
browsers out there support it.</li>
<li>Mature and stable for several years (although it's apparently <a
href="http://www.mozilla.org/projects/deerpark/new-web-dev-features.html">evolving
again</a>).</li>
<li>Formally standardized by multiple <a
href="http://www.ecma-international.org/publications/standards/Stnindex.htm">ECMA</a>
specs.</li>
<li>Familiar to Java programmers, with virtually the same syntax.</li>
<li>Very small. Its runtime adds 660Kb (uncompressed) to Mustang.</li>
</ul>
It is very difficult for any other scripting language to compete with
the list above. BeanShell and Pnuts are not popular enough, and as
programming languages they don't add anything, only
relaxed syntax. Groovy is not even at v1.0, and programming languages
are slow to mature. Even if
Groovy
reached a nice FCS in time for Mustang, I'm 100% against the
inclusion of any full-new language in the J2SE. The core Java platform
must hold very high standards for stability and compatibility, and you
really don't want the integration of a language that's still in a stage
of fast evolution, trust me. Languages like Ruby and Python are
cool and mature, but
their pure Java ports are lagging a lot behind the latest reference
implementations. And those more "respectable" languages are bigger –
exactly because they are mature languages that try to be useful on
their own, so they need a standard library of APIs of
reasonable size, and it's these libraries that make the languages big.
There is no competition to Javascript, because Javascript doesn't need
any APIs – it was designed to piggyback on interfaces exposed by web
browsers, like the DOM tree, which serve as the API for
scripts living in HTML pages, but are irrelevant outside a browser.
This explains why a complete Javascript
runtime fits in little over half megabyte. Even Groovy, which is
designed to depend on the J2SE APIs, is several times bigger (even
after you cut all redundant stuff, like XML parsers and other things
that are/will be already bundled by the J2SE).<br>
<br>
Not that I am completely happy with Javascript either. For one thing, I
think Javascript should be updated with some new goodies of <a
href="http://jcp.org/en/jsr/detail?id=201">JSR-201</a> like
enhanced-for and varargs. Otherwise, it will be funny that a scripting
language
may be often more verbose and less productive than its more
conventional counterpart, Java.<br>
<br>
The real question here is whether we should have <span
style="font-style: italic;">any </span>scripting
language included in the J2SE. The <a
href="http://jcp.org/en/jsr/detail?id=223">JSR-223</a> abstract
package, javax.script, is small (~26Kb), but I always wonder if it's a
good idea to put in
the core an API without a concrete implementation. It smells to
vaporware, and slows the adoption of the new API significantly. A good
case against bundling is when you can't have a single RI that works
for everybody, e.g. for JDBC drivers (and even in that case, there is
the bundled JdbcOdbc driver!). In the domain of scripting
languages, you can have an implementation that works in all
environments, but different users want completely
different languages. Well, I don't really
know what is the best option here.<br>
<br>
I guess that this bundling of <a href="http://www.mozilla.org/rhino/">Rhino</a>
would be
more firmly justified if it was useful to other J2SE 6.0 features.
Mustang is <a
href="http://java.sun.com/developer/technicalArticles/J2SE/Desktop/Mustang_build39.html">planned</a>
to have some sort of shell utility based on JSR201, that will be great
for quick exploration, and integrate with the J2SE's growing
serviceability features. This is a great dog-feeding of JSR201 and it
demands the bundling of a concrete scripting implementation; but it's a
developer-side feature that could be well served by bundling in the
J2SDK's tool.jar. Another interesting use of Rhino is found in Cocoon,
where Javascript's support for continuations makes possible a <a
href="http://www-106.ibm.com/developerworks/library/j-contin.html">programming
model</a> that may well be the next big thing in web frameworks. Truly
cool stuff, but not a case for J2SE bundling either, since it would be
good enough to include Rhino in J2EE 6.0 and future versions of
Servlets / JSP / JSF / whatever. We're still missing a killer app for
scripting in the
JRE. One idea: Swing's aging HTML component might become capable of
DHTML behaviors
(I'm not much of a client-side developer and I don't know how cool is
this idea, perhaps it's good for JavaHelp?). Any other ideas?]]>

</content>
</entry>
<entry>
<title>Opening Java</title>
<link rel="alternate" type="text/html" href="http://weblogs.java.net/blog/opinali/archive/2005/05/opening_java_1.html" />
<modified>2008-01-02T17:42:16Z</modified>
<issued>2005-05-21T16:28:00Z</issued>
<id>tag:weblogs.java.net,2005:/blog/opinali/232.2473</id>
<created>2005-05-21T16:28:00Z</created>
<summary type="text/plain">A comprehensive analysis of the debate over Free/OpenSource Java.</summary>
<author>
<name>opinali</name>

<email>osvaldo@visionnaire.com.br</email>
</author>
<dc:subject>Open Source</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://weblogs.java.net/blog/opinali/">
<![CDATA[<p>I&#8217;ve been a close observer of the evolution of the Java
platform, and one of the aspects that attracted me since the beginning
was its openness. Back in <a
	href="http://java.sun.com/features/2000/06/time-line.html">1996</a>,
the JDK 1.0 bundled source code for all public API classes (378Kb!). It
was also multiplatform in respect to OS &amp; hardware platforms, and
soon a strong multi-vendor platform. As a binary standard, it succeeded
where <a href="http://www.omg.org/">paper-only</a> or <a
	href="http://www.amazon.com/exec/obidos/tg/detail/-/0201700735/qid=1115913391/sr=1-1/ref=sr_1_1/103-0288874-9899830">source-level</a>
standards failed. Java was a big step forward.</p>
<p>But that was ten years ago, when free / open-source software (FOSS)
was also warming up. For example, Eric Raymond&#8217;s <a
	href="http://www.catb.org/%7Eesr/writings/cathedral-bazaar/">TCATB</a>
would appear only 1+ year later&nbsp; (May &#8216;97), and it was
visionary at that time. Today, Java is huge, the top business app
development platform. Meanwhile, FOSS increased in importance, volume
and mindshare by orders of magnitude, and it has also become <a
	href="http://www.research.ibm.com/journal/sj44-2.html">serious business</a>.</p>
<p>Unfortunately, Java is increasingly seen as a problem in the POV of
FOSS users and developers. This is despite many significant improvements
in openness since &#8216;96:</p>
<p><b>Full source code is <a
	href="http://java.sun.com/j2se/1.5.0/download.jsp">available</a>,
including Sun&#8217;s crown jewels like HotSpot.</b></p>
<p>The first SCSL releases used to be made available several months
late, and updated only for major releases, so only licensees who pay a
big fee had full access to up-to-date sources. But now with the <a
	href="https://mustang.dev.java.net/">Mustang</a> projects, the public
sources are updated weekly, so anybody can track its development as
closely as for any traditional open source project.</p>
<p><b>The <a href="http://jcp.org/">JCP</a> is an effective forum to
drive Java standards in an open way.</b></p>
<p>It&#8217;s less open than projects driven by public forums and more
relaxed steering committees (no fees for influential positions, no
strong dependency on proprietary software vendors, pure meritocracy,
etc.). But every model has its tradeoffs, and not everybody is convinced
that a &#8220;Pure Open&#8221; model would scale to the technical and
business realities of J2SE.</p>
<p><b>The relationship between Sun, the JCP, and other commercial
backers of Java, and the FOSS community, is very strong.</b></p>
<p>The latest version of the JCP&#8217;s process (<a
	href="http://jcp.org/en/procedures/jcp2">JCP 2.6</a>) certifies that
open source groups can implement any JSR, and makes the JSR works more
transparent for outsiders. The major Java vendors have strong
participation in FOSS projects like those from Apache and Eclipse, not
to mention others not directly related to Java, like <a
	href="http://kernel.org/">Linux</a> or <a
	href="http://opensolaris.org/">OpenSolaris</a>. In fact many JSRs have
their Reference Implementations delegated to FOSS projects, historically
under the umbrella of <a href="http://jakarta.apache.org/">Apache
Jakarta</a> and more recently in <a href="https://www.dev.java.net/">java.net</a>.</p>
<p><b>Java was always a great player with open standards in general.</b></p>
<p>Many non-Java developers have the impression that we like to reinvent
the wheel, creating our own incarnations of everything. The truth is
that we just create new implementations of everything. For example, a
Java webserver like <a href="http://jakarta.apache.org/tomcat">Tomcat</a>
doesn&#8217;t reinvent any wheel or break any standard: it strictly
adheres to relevant standards, like HTTP. Somebody could ask why
don&#8217;t we simply use (and contribute to) an existing free <a
	href="http://httpd.apache.org/">httpd</a>, adding new modules for
Java-specific technologies like <a
	href="http://java.sun.com/products/jsp/">JSP</a>. But the reason for
not doing this is <i>not </i>just the WORA mission. The full vertical
integration of the software stack, possible when everything is written
in Java and optimized for Java, is advantageous in many fronts, from
performance to ease of development and extensibility. The major reasons
why <a href="http://www.perl.org/">other</a> <a
	href="http://python.org/">people</a> don&#8217;t do the same are that
their languages don&#8217;t have sufficient performance for systems /
middleware programming, or their communities are not big enough to
support such projects.</p>
<p>Having said that, Java is not yet true <a
	href="http://opensource.org/licenses/">Open Source</a> or true <a
	href="http://www.fsf.org/licensing/licenses/">Free Software</a>.
Sun&#8217;s licenses, <a
	href="http://java.sun.com/j2se/1.5.0/scsl_5.0-license.txt">SCSL</a> and
<a href="http://java.sun.com/j2se/1.5.0/scsl_5.0-license.txt">JRL</a>,
don&#8217;t grant all rights required by the FOSS communities (Bruno
Souza <a
	href="http://www.javalobby.org/forums/thread.jspa?messageID=91825170#91825217">explains
this</a> in detail). Sun says they want to avoid a proliferation of
dialects of the platform. You may think this is very unlikely because
few people will be interested in making changes to the Java language or
creating new core APIs. But these are not the only sources of
&#8216;dialectization&#8217;. You just have to introduce a new bug, one
that would create a <a href="http://jcp.org/en/resources/tdk">JCK</a>
failure, and the damage is done: it&#8217;s not Java anymore.</p>
<p>How justified is this argument? We can answer this by checking
current FOSS Java projects, like <a
	href="http://www.gnu.org/software/classpath/classpath.html">Classpath</a>,
<a href="http://gcc.gnu.org/java/">GCJ</a> and <a
	href="http://www.kaffe.org/">Kaffe</a>. These projects do a pretty good
job in respecting Java standards. They don&#8217;t add any new public
APIs, and their compatibility issues are related to insufficient
resources to catch up with the proprietary implementations and to lack
of access to the JCK under acceptable terms (this is just fixed with
J2SE 5.0). So the community has even started its own free replacement
for the JCK, <a href="http://sources.redhat.com/mauve/">Mauve</a>
&#8211; a strong evidence of the commitment of the FOSS developers to
Java compliance. (But I would be too forgiving to ignore GCJ&#8217;s <a
	href="http://gcc.gnu.org/onlinedocs/gcj/About-CNI.html">CNI</a>, a
proprietary native interface that competes with JNI, and has no reason
to exist, except for the immaturity of GCJ. Microsoft also did have good
technical excuses for the extensions they created long ago. Dear GCJ
developers, please kill this bastard; CNI gives reason to all the
paranoids that think opening Java is killing its WORA.)</p>
<p>Java has become too important to be ignored even by those old-school
FOSS developers who still love lower-level tools like C. FSF leader
Richard Stallman&#8217;s <a
	href="http://www.gnu.org/philosophy/java-trap.html">Java Trap</a> paper
puts this in good perspective. RMS doesn&#8217;t seem to be a big fan of
Java (&#8220;<i>people who write free software often feel Java is
sexy&#8230;</i>&#8221;), but he admits that just not using Java is not
an option. The world is now full of Java code and Java programmers, and
the only viable solution is having a Free Java implementation. This
debate is getting hotter by the day. We recently saw the FSF <a
	href="http://news.yahoo.com/news?tmpl=story&amp;u=/zd/20050509/tc_zd/151511">complaining
about the growing use of Java in OpenOffice</a>. I think that if this
community didn&#8217;t have resources to <a
	href="http://office.microsoft.com/">compete</a> alone in this field,
they should be happy that Sun has made OO possible. Of course Sun will
put Java wherever it&#8217;s a good fit. I was amused by the FSF&#8217;s
initial reaction, hinting towards a fork of OO to drop, or re-implement
in other languages, the pieces that use Java. This is IMHO something
that should not happen in a healthy FOSS community &#8211; and those who
value the Free Software ideology over features could easily pick <a
	href="http://www.koffice.org/">other choices</a>. <a
	href="http://software.newsforge.com/software/05/05/16/1358227.shtml?tid=152&amp;tid=150&amp;tid=89&amp;tid=93&amp;tid=132">Fortunately</a>,
it seems that the FSF is going to do <a
	href="http://www.fsf.org/news/open-office-java.html">the right thing</a>:
tweak OO and/or improve <a href="http://gcc.gnu.org/java/">GCJ</a> until
they work together, so OpenOffice 2.0 offers a 100% Free build for those
who care. I am one of those who won&#8217;t use that (when OO2 goes FCS,
I will certainly run it atop any JVM that deliver the best
stability&nbsp; and performance) so I don&#8217;t like the additional
delay imposed by this solution. But looking from the Forest view, I
think it&#8217;s a good thing: OO is not the only software that will
benefit from improved Free Java implementations, and these improvements
may increase the popularity of Java with Free software users. After all,
there is a whole boatload of high-quality <a
	href="http://sourceforge.net/softwaremap/trove_list.php?form_cat=198">Free</a>
<a href="https://www.dev.java.net/servlets/ProjectList">Java</a> <a
	href="http://jakarta.apache.org/">software</a> out there. Any effort
spent in converting Java to C for specific apps, even important ones
like OO, is wasted effort, in perspective.</p>
<p>The other big news is Apache&#8217;s newly-incubated <a
	href="http://mail-archives.apache.org/mod_mbox/incubator-general/200505.mbox/%3cCA4BEB82-3D84-457D-9531-1477DD749919@apache.org%3e">Harmony</a>.
Everybody is blogging over Harmony, so I will try to add some new
thoughts. Harmony intends to build a complete, compliant J2SE
implementation, which is a step forward compared to VM- or library-only
projects. They are talking to the FSF over Classpath, because without
reusing that, the project is not viable, as the J2SE APIs are too big
and fast-moving. I&#8217;m very curious about the reaction of some
players, like IBM, who has been <a
	href="http://news.com.com/2100-1007_3-5165427.html?tag=nefd_top">pushing
Sun publicly</a> towards open-sourcing Java. Well, IBM owns at least two
completely clean-room, production-quality JVMs (IBM JDK and J9), and it
seems they have reimplemented large chunks of the APIs too, especially
the most difficult ones like CORBA and Security. AFAIK they can open
these sources without breaking contract with Sun. And it&#8217;s not
just IBM; BEA has also became a competitive player recently with <a
	href="http://www.bea.com/framework.jsp?CNT=index.htm&amp;FP=/content/products/jrockit">JRockit</a>,
and Apple, while not in the clean-room team, has made many significant
improvements to HotSpot and APIs like Swing.</p>
<p>But I don&#8217;t think this is a simple case of cheap talk.
It&#8217;s more likely a case of &#8220;<i>we&#8217;re not giving away
our competitive advantage, at least not alone</i>&#8221;. For major Java
players, having their own proprietary JVM is strategic: to have control
over its implementation (e.g. to fix bugs that are important to their
own customers), add optimizations for your hardware or application
server and vice-versa. This is also the reason why just pledging Sun to
unilaterally opensource Java has little chance to work. These companies
will not open the code for their Java technology before they sit
together and find a common solution, one that doesn&#8217;t risk
anybody&#8217;s business plans. (And Sun must<i> </i>be part of the
solution, because nobody else has complete clean-room APIs.) Perhaps the
best alternative is <a
	href="http://weblogs.java.net/blog/kgh/archive/2005/05/thoughts_on_the_1.html">endorsing</a>
a new, independent Free Java project like Harmony, as those big
companies know that such project, even with significant resources, will
take several years to start competing with proprietary JVMs, if not in
compliance certainly in performance. Then Sun, IBM, BEA and others can
play nice, even donating resources and developer time to Harmony, while
still boasting their superior proprietary implementations whenever
it&#8217;s good for business. Some day, a great J2SE implementation will
be a commodity, but this day is not today. And if you ask me,
there&#8217;s nothing wrong with this strategy.</p>
<p>Should a full, top-notch J2SE implementation go Free today, we
wouldn&#8217;t need Harmony, but then we might worry about potential
&#8220;misuse&#8221; of these sources. The risk of forking has been
discussed to death and I don&#8217;t think it&#8217;s big: the Java
community has a strong culture of following its standards, and the
current status of Free implementations that are not compliant because
they can&#8217;t is worse than any purposeful forking. A second
possibility is that Java code could be useful for <i>competing </i>platforms.
This risk is significant, as <a
	href="http://msdn.microsoft.com/netframework/">.NET</a> is a strong
competitor that&#8217;s also similar enough to Java to allow easy
porting. I don&#8217;t think Microsoft would do that, but I wonder about
FOSS .NET projects, like <a href="http://mono-project.com/">Mono</a> or
<a href="http://www.dotgnu.org/">DotGNU</a>. These projects are way
behind the proprietary VMs (either Java or .NET); and their developers
obviously like .NET better than Java, or perhaps for DotGNU, value their
Free agenda more than any of the competing platforms. There are VM
projects like <a href="http://cs.anu.edu.au/%7EAndrew.Gray/rmtk/">RMTk</a>,
and library projects like <a href="http://www.nunit.org/">NUnit</a>,
providing evidence that Java code can be used to accelerate the
production of similar .NET software. Not to mention &#8220;hybrid&#8221;
solutions like <a href="http://www.ikvm.net/">IKVM</a>, that allows
running unchanged Java code on .NET runtimes. Even if the Java code is
eventually replaced by new code, written from scratch to better explore
.NET&#8217;s style and frameworks, the Java code is very useful for
prototyping and to make initial versions available quickly. In an ideal
world, both communities could benefit from each other&#8217;s work, but
in practice, the numbers of Java are still vastly superior to
.NET&#8217;s, so we&#8217;re just giving away and not receiving anything
back. Companies with a large investment in Java might worry about giving
away technology to the competition. They could use viral licenses like
the <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> or <a
	href="http://www.sun.com/cddl/cddl.html">CDDL</a>, so the Java code
cannot be used in proprietary .NET products that are their main
competition, but this won&#8217;t prevent that code to foster the
opensource .NET offerings. But in the bright side (and now I&#8217;m
dropping my Java-advocate hat to say this), the migration of code from
Java to NET, and eventually vice-versa, is interesting from the
interoperability point of view, as we tend to have more compatibility
between software of both worlds.</p>
<p>The whole debate is even more interesting when we inspect Sun
Microsystem&#8217;s overall behavior towards open source. We have to
commend Sun not only for past glory like NFS, but for very important,
high-profile open source efforts like OpenOffice, NetBeans and
OpenSolaris. The latter, btw, is supposed to <a
	href="http://www.techworld.com/opsys/news/index.cfm?newsid=3607">deliver
the promised source code by mid-June</a>. (Solaris X will be very
appealing to advanced Java developers as soon as <a
	href="https://solaris10-dtrace-vm-agents.dev.java.net/">DTrace supports
Java</a>.) And the weirdest thing is that in these other opensource
efforts, Sun <i>doesn&#8217;t</i> have any problem with real FOSS
licenses. In OpenSolaris, Sun even adopted a &#8220;viral&#8221;,
MPL-like <a href="http://www.sun.com/cddl/cddl.html">license</a>,
perhaps with the same logic of not helping competitors with proprietary
OSes, or even <a href="http://www.redhat.com/">Free</a> ones. And while
some people inside Sun are very vocal in favor of open source, <a
	href="http://today.java.net/jag/">James Gosling</a> is not, saying that
many customers would <a
	href="http://www.devx.com/Java/Article/28125?trk=DXRSS_LATEST">&#8220;freak..
screaming to the hills&#8221;</a> over the prospect of opensourcing
Java. I admire James for his brave words, in a time when being
anti-opensource is almost politically incorrect &#8211; I&#8217;m just
waiting for the <a href="http://slashdot.org/">Free zealots</a>
comparing JG to Bill Gates due to this quote. <i>I </i>would certainly
&#8220;freak out&#8221; if Sun just opened CVS access to the J2SE
project so anybody could check code in. But no serious opensource
project works that way, they have layers of leadership and code
reviewers to validate contributions; and James knows it, and this
didn&#8217;t stop Sun from opening Solaris. Check the <a
	href="http://opensolaris.org/roadmap/index.html">OpenSolaris roadmap</a>
for this, they have planned a process to make external contributions
possible without wrecking the quality of the Solaris product. In the <a
	href="https://mustang.dev.java.net/">Mustang</a> project, even at this
stage (without full opensourcing), Sun has also put together the <a
	href="http://java.sun.com/developer/technicalArticles/J2SE/peabody/">basic
process and infra-structure</a> for <a
	href="http://www.javalobby.org/articles/fixing-the-jdk/">contributions</a>.
I say &#8220;basic&#8221; because they won&#8217;t have a significant
volume of contribution before they have a FOSS license, but it&#8217;s a
solid step towards full opensourcing if this ever happens. Now, with
respect to freaking customers, Sun should do some customer education
before they opensource Java, just like (I guess) they have/will do for
Solaris. It&#8217;s just a matter of making clear that the huge
engineering and QA effort that was put into J2SE will not be
compromised. This implies that, if Sun opensources their implementation
of J2SE, they should do that in a way that keeps enough control so they
can enforce their standards and vision. Look no further than <a
	href="http://www.eclipse.org/">Eclipse</a>, which organization and
process was recently <a
	href="http://weblogs.java.net/blog/timboudreau/archive/2005/04/am_i_the_only_o.html">criticized</a>
for being less open than other FOSS projects&#8230; well, as a satisfied
user of Eclipse, I think its governance is ideal like it is, and it
seems that OpenSolaris won&#8217;t deviate much from that model: Sun
will obviously keep a very strong leading position... anyway, Free Java is probably not going to happen that way.
</p>
<p>
So, what about
Harmony? It&#8217;s an excellent move from the Free community, probably
the best (or only) viable way to produce a Free implementation of J2SE,
and then increase even further the penetration of the Java platform.
Now, if they have as much success as I wish, and in a few years we have
a complete, high-performance Free Java, then we will have real answers
to the big questions posed here: whether a &#8220;pure&#8221; FOSS
project can deal with something as complex as a production-quality J2SE
platform, and whether any of the FUD against Free Java is justified.</p>]]>

</content>
</entry>

</feed>