Saturday, November 13, 2010

Jeans - Running Java Servlet and JSP Webapp in ASP.NET/IIS - Part 2

One of my mentors said, "If you do not write SQL, you cannot do application development." Even though the statement is not quite true as there are ORM frameworks handling the database communication, the statement emphasizes the importance of database. So, running a pure Hello World JSP is a poor proof of concept to ASP.NET. Running a database connected JSP is more meaningful.

Preparation
The following components were gathered in this phase:
  • JPA - the current standard of doing ORM in Java.
    •  EclipseLink is the reference implementation. It should serve the purpose well.
  • SQL Server 2008 Express - As ASP.NET is being used anyway, why don't we work in the whole Microsoft ecosystem?
    • SQL Server JDBC Driver - Yes, I need a JDBC Driver in .Net...
  • AdventureWorksLT - Microsoft used to provide sample databases that works with SQL Server. AdventureWorksLT is the simplified version.
One bottleneck I have is I have no JPA experience. I used Hibernate before but JPA is a standard. The problem of being standard is there are many implementations. The only way to understand it is to read the specification. Otherwise, it's hard to understand how it works in general so that it works for most (if not all) implementations.

META-INF/persistence.xml
One of the challenges encountered was loading the persistence.xml. Luckily, IKVM can load the resource files with by specifying -classloader:ikvm.runtime.ClassPathAssemblyClassLoader when the compiling the class files and JAR files into .Net assembly. However, since all files were compiled into a single DLL. Only the first persistence.xml IKVM read can managed to be the resource.

META-INF/orm.xml
The problem of compiling everything into .Net assembly is losing all annotations in the classes. In the other words, you must use META-INF/orm.xml and initialize it in an IHttpModule.

Rework
The limitation of loading the two XML files is quite nasty. It would not feasible for medium size application that might have a few JAR files containing persistence.xml. Creating orm.xml manually is quite a pain as you know the information is in the classes already. To increase the flexbility, ClassPathAssemblyClassLoader is is wrapped by an URLClassLoader with the following classpaths:
  1. WEB-INF\classes 
  2. All JAR files in WEB-INF\lib directory
Then, it is invoked to the current thread's context class loader to load the JAR and the precompiled JSP classes directly. It works!

Dual Mode
Now, Jeans support two ways to run a Java webapp:
  1. Native mode - With everything compiled into a single DLL
  2. WAR mode - Run a standard Java webapp directory whose structure is the same as in WAR file given:
    1. JSP are precompiled into servlet and put into WEB-INF/classes folder.
    2. JSP Servlet mappings are stored in jspweb.xml to complement the original web.xml.
The consequence is quite obvious. In native mode, it takes around 50MB of memory to load the Hello World page. In WAR mode, it takes around 100MB of memory the run the same page. No benchmark for the application performance but I believed native mode should run faster.

No comments: