Friday, December 08, 2006

Are you suffering from using Dojo in Grails ?

Everything works fine for Grails 0.3.1 when I'm not using Dojo.
But after I'm using it with Grails, I'm suffering from the 100% CPU usage.
This performance hit's caused by Jetty (Grails' default server) is trying to response Dojo files.

From my understanding, it might be that
1. Jetty in Grails distribution has not been configured for this purpose ? or
2. It's normal that a Servlet container's not good at serving a big static file ?

Anyway, I still don't know what's going on inside the container, but I've got a workaround for this problem.
My current solution is to use lighttpd as the front server to serve this Dojo monster ;)
I connect lighttpd with Grails' server using the mod_proxy.
Here's my current config in \etc\lighttpd.conf


proxy.server = ( "/" =>
( "127.0.0.1" =>
(
"host" => "127.0.0.1",
"port" => 8080
)
)
)



Then you need to put your Dojo files into the \htdocs, and correct all script's references in your GSP pages.
Lighttpd uses the default 80 port. So, you just point your browser to http://127.0.0.1//, every should work correctly.

IMO, this solution should work for the production phase as well.

Friday, December 01, 2006

Minimum "rt.jar" for Hello World

Here's a list of classes that are needed to run a Java hello world program.
I find this list using java -verbose (motivated by this post).

== listfile.txt ==
/java/io/BufferedInputStream.class
/java/io/BufferedOutputStream.class
/java/io/BufferedWriter.class
/java/io/Closeable.class
/java/io/DataInput.class
/java/io/DataInputStream.class
/java/io/ExpiringCache.class
/java/io/ExpiringCache$1.class
/java/io/ExpiringCache$Entry.class
/java/io/File.class
/java/io/FileDescriptor.class
/java/io/FileInputStream.class
/java/io/FileOutputStream.class
/java/io/FilePermission.class
/java/io/FilePermission$1.class
/java/io/FilePermissionCollection.class
/java/io/FileSystem.class
/java/io/FilterInputStream.class
/java/io/FilterOutputStream.class
/java/io/Flushable.class
/java/io/InputStream.class
/java/io/ObjectStreamClass.class
/java/io/ObjectStreamField.class
/java/io/OutputStream.class
/java/io/OutputStreamWriter.class
/java/io/PrintStream.class
/java/io/Serializable.class
/java/io/Win32FileSystem.class
/java/io/WinNTFileSystem.class
/java/io/Writer.class
/java/lang/AbstractStringBuilder.class
/java/lang/Appendable.class
/java/lang/ArithmeticException.class
/java/lang/ArrayStoreException.class
/java/lang/Boolean.class
/java/lang/Byte.class
/java/lang/CharSequence.class
/java/lang/Character.class
/java/lang/CharacterDataLatin1.class
/java/lang/Class.class
/java/lang/Class$1.class
/java/lang/Class$3.class
/java/lang/ClassCastException.class
/java/lang/ClassLoader.class
/java/lang/ClassLoader$3.class
/java/lang/ClassLoader$NativeLibrary.class
/java/lang/ClassNotFoundException.class
/java/lang/Cloneable.class
/java/lang/Comparable.class
/java/lang/Compiler.class
/java/lang/Compiler$1.class
/java/lang/Double.class
/java/lang/Error.class
/java/lang/Exception.class
/java/lang/Float.class
/java/lang/IncompatibleClassChangeError.class
/java/lang/Integer.class
/java/lang/Iterable.class
/java/lang/LinkageError.class
/java/lang/Long.class
/java/lang/Math.class
/java/lang/NoClassDefFoundError.class
/java/lang/NoSuchMethodError.class
/java/lang/NullPointerException.class
/java/lang/Number.class
/java/lang/Object.class
/java/lang/OutOfMemoryError.class
/java/lang/Readable.class
/java/lang/Runnable.class
/java/lang/Runtime.class
/java/lang/RuntimeException.class
/java/lang/RuntimePermission.class
/java/lang/Short.class
/java/lang/Shutdown.class
/java/lang/Shutdown$Lock.class
/java/lang/StackOverflowError.class
/java/lang/StackTraceElement.class
/java/lang/StrictMath.class
/java/lang/String.class
/java/lang/String$CaseInsensitiveComparator.class
/java/lang/StringBuffer.class
/java/lang/StringBuilder.class
/java/lang/StringCoding.class
/java/lang/StringCoding$CharsetSD.class
/java/lang/StringCoding$CharsetSE.class
/java/lang/StringCoding$StringDecoder.class
/java/lang/StringCoding$StringEncoder.class
/java/lang/System.class
/java/lang/System$2.class
/java/lang/SystemClassLoaderAction.class
/java/lang/Terminator.class
/java/lang/Terminator$1.class
/java/lang/Thread.class
/java/lang/Thread$UncaughtExceptionHandler.class
/java/lang/ThreadDeath.class
/java/lang/ThreadGroup.class
/java/lang/ThreadLocal.class
/java/lang/ThreadLocal$ThreadLocalMap.class
/java/lang/ThreadLocal$ThreadLocalMap$Entry.class
/java/lang/Throwable.class
/java/lang/VirtualMachineError.class
/java/lang/annotation/Annotation.class
/java/lang/management/MemoryUsage.class
/java/lang/ref/FinalReference.class
/java/lang/ref/Finalizer.class
/java/lang/ref/Finalizer$FinalizerThread.class
/java/lang/ref/PhantomReference.class
/java/lang/ref/Reference.class
/java/lang/ref/Reference$Lock.class
/java/lang/ref/Reference$ReferenceHandler.class
/java/lang/ref/ReferenceQueue.class
/java/lang/ref/ReferenceQueue$Lock.class
/java/lang/ref/ReferenceQueue$Null.class
/java/lang/ref/SoftReference.class
/java/lang/ref/WeakReference.class
/java/lang/reflect/AccessibleObject.class
/java/lang/reflect/AnnotatedElement.class
/java/lang/reflect/Constructor.class
/java/lang/reflect/Field.class
/java/lang/reflect/GenericDeclaration.class
/java/lang/reflect/Member.class
/java/lang/reflect/Method.class
/java/lang/reflect/Modifier.class
/java/lang/reflect/ReflectAccess.class
/java/lang/reflect/ReflectPermission.class
/java/lang/reflect/Type.class
/java/net/ContentHandler.class
/java/net/Parts.class
/java/net/URL.class
/java/net/URLClassLoader.class
/java/net/URLClassLoader$1.class
/java/net/URLConnection.class
/java/net/URLStreamHandler.class
/java/net/URLStreamHandlerFactory.class
/java/net/UnknownContentHandler.class
/java/nio/Bits.class
/java/nio/Buffer.class
/java/nio/ByteBuffer.class
/java/nio/ByteOrder.class
/java/nio/CharBuffer.class
/java/nio/HeapByteBuffer.class
/java/nio/HeapCharBuffer.class
/java/nio/charset/Charset.class
/java/nio/charset/Charset$3.class
/java/nio/charset/CharsetDecoder.class
/java/nio/charset/CharsetEncoder.class
/java/nio/charset/CoderResult.class
/java/nio/charset/CoderResult$1.class
/java/nio/charset/CoderResult$2.class
/java/nio/charset/CoderResult$Cache.class
/java/nio/charset/CodingErrorAction.class
/java/nio/charset/spi/CharsetProvider.class
/java/security/AccessControlContext.class
/java/security/AccessController.class
/java/security/AllPermission.class
/java/security/BasicPermission.class
/java/security/BasicPermissionCollection.class
/java/security/CodeSource.class
/java/security/Guard.class
/java/security/Permission.class
/java/security/PermissionCollection.class
/java/security/Permissions.class
/java/security/Principal.class
/java/security/PrivilegedAction.class
/java/security/PrivilegedActionException.class
/java/security/PrivilegedExceptionAction.class
/java/security/ProtectionDomain.class
/java/security/SecureClassLoader.class
/java/security/UnresolvedPermission.class
/java/security/cert/Certificate.class
/java/util/AbstractCollection.class
/java/util/AbstractList.class
/java/util/AbstractMap.class
/java/util/AbstractSet.class
/java/util/ArrayList.class
/java/util/BitSet.class
/java/util/Collection.class
/java/util/Collections.class
/java/util/Collections$EmptyList.class
/java/util/Collections$EmptyMap.class
/java/util/Collections$EmptySet.class
/java/util/Collections$ReverseComparator.class
/java/util/Collections$SynchronizedMap.class
/java/util/Comparator.class
/java/util/Dictionary.class
/java/util/Enumeration.class
/java/util/HashMap.class
/java/util/HashMap$Entry.class
/java/util/HashSet.class
/java/util/Hashtable.class
/java/util/Hashtable$EmptyEnumerator.class
/java/util/Hashtable$EmptyIterator.class
/java/util/Hashtable$Entry.class
/java/util/Iterator.class
/java/util/LinkedHashMap.class
/java/util/LinkedHashMap$Entry.class
/java/util/List.class
/java/util/Locale.class
/java/util/Map.class
/java/util/Map$Entry.class
/java/util/Properties.class
/java/util/Random.class
/java/util/RandomAccess.class
/java/util/Set.class
/java/util/SortedMap.class
/java/util/Stack.class
/java/util/StringTokenizer.class
/java/util/TreeMap.class
/java/util/TreeMap$Entry.class
/java/util/Vector.class
/java/util/concurrent/atomic/AtomicLong.class
/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.class
/java/util/concurrent/atomic/AtomicReferenceFieldUpdater$AtomicReferenceFieldUpdaterImpl.class
/java/util/jar/JarEntry.class
/java/util/jar/JarFile.class
/java/util/jar/JarFile$JarFileEntry.class
/java/util/jar/JavaUtilJarAccessImpl.class
/java/util/zip/Inflater.class
/java/util/zip/InflaterInputStream.class
/java/util/zip/ZipConstants.class
/java/util/zip/ZipEntry.class
/java/util/zip/ZipFile.class
/java/util/zip/ZipFile$2.class
/java/util/zip/ZipFile$ZipFileInputStream.class
/sun/io/Converters.class
/sun/misc/ASCIICaseInsensitiveComparator.class
/sun/misc/AtomicLong.class
/sun/misc/AtomicLongCSImpl.class
/sun/misc/ExtensionDependency.class
/sun/misc/FileURLMapper.class
/sun/misc/JarIndex.class
/sun/misc/JavaLangAccess.class
/sun/misc/JavaUtilJarAccess.class
/sun/misc/Launcher.class
/sun/misc/Launcher$AppClassLoader.class
/sun/misc/Launcher$AppClassLoader$1.class
/sun/misc/Launcher$ExtClassLoader.class
/sun/misc/Launcher$ExtClassLoader$1.class
/sun/misc/Launcher$Factory.class
/sun/misc/NativeSignalHandler.class
/sun/misc/Resource.class
/sun/misc/SharedSecrets.class
/sun/misc/Signal.class
/sun/misc/SignalHandler.class
/sun/misc/SoftCache.class
/sun/misc/URLClassPath.class
/sun/misc/URLClassPath$3.class
/sun/misc/URLClassPath$FileLoader.class
/sun/misc/URLClassPath$FileLoader$1.class
/sun/misc/URLClassPath$JarLoader.class
/sun/misc/URLClassPath$Loader.class
/sun/misc/Unsafe.class
/sun/misc/VM.class
/sun/misc/Version.class
/sun/net/www/MessageHeader.class
/sun/net/www/ParseUtil.class
/sun/net/www/URLConnection.class
/sun/net/www/protocol/file/FileURLConnection.class
/sun/net/www/protocol/file/Handler.class
/sun/net/www/protocol/jar/Handler.class
/sun/nio/ByteBuffered.class
/sun/nio/cs/AbstractCharsetProvider.class
/sun/nio/cs/FastCharsetProvider.class
/sun/nio/cs/HistoricallyNamedCharset.class
/sun/nio/cs/MS1252.class
/sun/nio/cs/MS1252$Decoder.class
/sun/nio/cs/MS1252$Encoder.class
/sun/nio/cs/SingleByteDecoder.class
/sun/nio/cs/SingleByteEncoder.class
/sun/nio/cs/StandardCharsets.class
/sun/nio/cs/StandardCharsets$Aliases.class
/sun/nio/cs/StandardCharsets$Cache.class
/sun/nio/cs/StandardCharsets$Classes.class
/sun/nio/cs/StreamEncoder.class
/sun/nio/cs/StreamEncoder$CharsetSE.class
/sun/nio/cs/Surrogate.class
/sun/nio/cs/Surrogate$Parser.class
/sun/nio/cs/ext/ExtendedCharsets.class
/sun/nio/cs/ext/MS874.class
/sun/nio/cs/ext/MS874$Decoder.class
/sun/nio/cs/ext/MS874$Encoder.class
/sun/reflect/ConstantPool.class
/sun/reflect/ConstructorAccessor.class
/sun/reflect/ConstructorAccessorImpl.class
/sun/reflect/DelegatingClassLoader.class
/sun/reflect/DelegatingConstructorAccessorImpl.class
/sun/reflect/LangReflectAccess.class
/sun/reflect/MagicAccessorImpl.class
/sun/reflect/MethodAccessor.class
/sun/reflect/MethodAccessorImpl.class
/sun/reflect/NativeConstructorAccessorImpl.class
/sun/reflect/Reflection.class
/sun/reflect/ReflectionFactory.class
/sun/reflect/ReflectionFactory$1.class
/sun/reflect/ReflectionFactory$GetReflectionFactoryAction.class
/sun/reflect/misc/ReflectUtil.class
/sun/security/action/GetPropertyAction.class
/sun/security/util/Debug.class
/sun/util/PreHashedMap.class



The following is a command for 7z to strip down the rt.jar (from 37,043 Kb to 1,806 Kb).

7z.exe d -r -x@listfile.txt rt.jar *.class



I tested with JRE 1.5_08 on Windows XP.

Saturday, April 08, 2006

Practical AOP #2 - What's done behind-the-scene?

I'll show you something that I think it's hard to maintain without AOP.
As in my Practical AOP #1, I mentioned that I have 8 inter-type declarations and 5 pointcuts to make data-binding work in ZK framework.

The main important thing is that I need one of the ZK base class to implement my Bindable interface. This change can be considered as somekind of the architectural change. Other point is that several UI element classes need to be modified. One of my pointcuts weaves to add the special event trigger to, at least, 9 classes.

The figure below partially shows the UML-like class diagram for the data-binding aspect.

AOP | Modularity ~= Responsibility

It's difficult to making change to many opensource projects that their developers are taking full responsibility to their own codes. The process of changing must be done via their process. Many projects use the opensource community to find their bugs rather than feature enhancement becuase the developer still want to control the way the project should be. This is somewhat to crash the innovations. Someone who has some ideas to completely enhace the original project has to *fork* to the new project. In my opinion, we can use AOP to solve these social phenomena.

What I've done is in the same way I mentioned above. At the first place, I want to add some new features to ZK. I created some new code and was thinking about sending the patch to ZK developers. But I stopped and thought again. If I send my patches to them, my code may break their code and it's not good for the ZK community. The development may have to be slow down because something will be patched into the core. So my solution is to convert all my new code into an aspect. Then I'll take all responsibilities to my aspect rather than push it to the ZK core developers. I think this solution could be good when someone wants to contribute a new thing to the core of some working frameworks. That's why the data-binding aspect has been made.

Practical AOP #1: Data-Binding Aspect for Web UI

ZK (http://zk1.sf.net) is one of the best XUL tool for Java that I've known. It's a very powerful framework working on server-side to render DHTML with Ajax capability. ZK is heavily based on MVC model, but I personally want to use the .NET-like data-binding feature in this framework. To avoid making changes direct to the ZK core, which is being maintained by its developers, I use AspectJ (1.5) to create the "data-binding" aspect.

However, I firstly started with OO approach in my development process. After I have some working code, I've tried to refactor the data-binding aspect out of the base code. During development, I've found that it is difficult to develop aspects without looking to the base source code. Because I need to ensure that my aspect weaves the base code correctly.

In my data-binding aspect, I have 5 pointcuts and 8 inter-type declarations.

Result
I've finished the first version of zk-databinding aspect outside the ZK team.
With AspectJ 1.5 and Java 5, I can deploy my aspect to a Web container (tested with
Tomcat 5.5.16) and get the data-binding feature transparently.
Not surprisingly, the data-binding aspect works with ZK 1.1 and ZK 1.2 flawlessly.

Wednesday, March 15, 2006

Together + NHibernate ~= A Great Duo

I just have an opportunity to use Borland Together 2005 for VS.NET. Its LiveSource ? feature is very cool !!!. So, I’m here to tell my experience.
I’m evaluating a modeling tool for modeling business sytem that will be implemented using NHibernate. This system will contains 70-80 classes (a small-medium system). Someone who visited my website may be wonder why I don’t use ECO III. The main reason is because ECO III doesn’t work will with MySQL dbms. The other reason is that ECO III uses the unified approach to maintain object id, so the system may have a number of objects no more that 2^31 (please correct me if I’m wrong). However, this limitation is not a problem for a small to medium system. I calculated that the system can run and work well for at least 50 years. But the problem will occur when there are a lot of transaction per day. Object ids will be run out, and ECO won’t reuse any deleted id.

On the other hand, NHibernate is boring because it cannot fully manage bi-directional associations because it isn’t controlled by a state machine, which ECO has. The main advantages of NHibernate are. 1. ) It allows developer to do o/r mapping at low-level, and 2.) NHibernate objects are plain .NET objects (while ECO objects are not, all ECO business entity implements IObject interface).

I’m evaluating DevExpress XtraGrid for UI layer, it’s amazing control. Not much needed to say. Its databinding ability is extremely cool !!. One problem I encountered for NHibernate with DevExpress and other GUI layer is just we need to implement Equals, ToString, Hash methods for every class. And I’m now ready to by XtraGrid :). FYI, I use ObjectViews to connect NHibernate to XtraGrid instead of ISet, IList or Array.

Back to Together, it is useful for modeling and it makes me wonder that why Together for VS.NET is faster that Together for Delphi (they should be share the same implementation, shouldn’t they.) Code synchronization is beautiful (v. SP1) I am much faster to model the business entity. AFAIK, Together is one of a few tools that allow designer to put some attributes to the design elements (class, method). I think Rational XDE also have this feature, but didn’t try yet. One feature I don’t see in Together is automatic field encapsulation as property, which is needed by NHibernate. May be I just don’t know how to use it (please tell me if you know). Other great features of Together are namespace management, and enum and inner class modeling, which may be useful for one who uses NHibernate. Together also provides very flexible refactoring.

Wednesday, January 18, 2006

Moved to Manchester

Long time no posting.
I'm very busy about moving from Thailand to Manchester, UK.
This is the first day in Manchester that I can online more than 3 hrs :).
I'll study a PhD research program at the University of Manchester for, at least, 3 years.