JSP at GlassFish
JSR 245 MR: Part 2 - JSP
This is the second part of the update on JSP and EL specification. A previous blog covers the EL MR. This blog covers the JSP Specification MR. The details can be obtained from here. The close date for the MR is March 3, 2009. Please send comments to me.
The proposed JSP MR fixes some typos and errors, and adds some minor enhancements to JSP. This blog covers these enhancements.
Declare Default Content Type
Currently, the default content type is
text/htmlfor JSP pages in standard syntax andtext/xmlfor pages in xml syntax. This can be overridden by the use the page directives in individual JSP pages. It would be sometimes desirable to set a content type, such astext/xhtml, for the whole application.The MR adds a JSP configuration element
default-content-typeto thejsp-property-groupelement. It can be used to set the default content type for a group of JSP pages that matches the URL pattern defined in thejsp-property-group.Set Default Buffer Size
Likewise, the MR adds a JSP configuration element
bufferto thejsp-property-group. It can be used to set the buffering model for a a group of JSP pages that matches the URL pattern defined in thejsp-property-group.Raise Errors for Undeclared Namespaces
Currently, using an unknown namespace in standard JSP syntax is silently ignored, but is an error in xml syntax. This is somewhat inconsistent, to say the least.
Moreover, it is a common mistaken to omit the declaration of a tag library using the taglib directive before it is used in a JSP page. The end result is that the tag library is not invoked, and nothing is displayed. This often a source for confusion to page authors.
As a remedy, we add a
error-on-undeclared-namespaceelement to thejsp-property-group. It can be used to force an error at compile time when undeclared namespaces are used in a group of JSP pages that matches the URL pattern defined in thejsp-property-group.-
Omit Generation of Attribute in <jsp:element>
<jsp:element>can be used to generate dynamic tag elements on the fly, and<jsp:attribute>can be used to generate an attribute for the element. However it is currently not possible to conditionally omit the attribute. The most we can do now is to generate an attribute with a null value, but is not the same as an omitted attribute, for some browsers.We now introduce an optional attribute
omitto<jsp:attribute>. When it evaluates totrue, the attribute is not generated in the<jsp:element>. Consider the following:<jsp:element name="image"> <jsp:attribute omit=${width eq null}> ${width} </jsp:attribute> <jsp:body> body </jsp:body> </jsp:element>Whenwidthis "100", for instance, the following is generated:<image width="100"> body </image>Whenwidthis null, the following is generated:<image> body </image>
The sources for the API and implementation will be done at the jsp project and will be bundled with Glassfish V3 release.
Posted at 04:54PM Feb 03, 2009 by kchung in Personal | Comments[0]
JSR 245 MR: Part I - Expression Language (EL)
This is a quick update on JSP and EL (Expression Language) specification.
Although the EL specification has been separated from the JSP specification, for various reasons, we have not taken the last step to create a new JSR for EL. The proposed work on the JSP MR and EL MR has been filed under JSR-245. The details can be obtained from here.
The close date for the MR is March 3, 2009. Please send comments to me.
This blog covers the EL MR.
One of the most requested feature enhancement to EL is the ability to invoke
methods in EL expressions. The MethodExpression in the current EL can be
used to specify a method in the EL expression. For instance, in the following
JSF code fragment,
<h:commandButton action="#{trader.buy}" value="buy"/>
the method buy in the bean trader is specified in EL. This method is
is not invoked here, but instead, it is passed to the tag handler, and
can only be invoked from Java codes. Also, the parameter types of the method cannot be
obtained from the EL expression, but must be specified in the TLD (Tag Library
Descriptor). At the method invocation, the actual arguments (also not
specified in the EL expression) are coerced to the corresponding parameter
types and passed to the method. As you can see, there are a lot things
that need to be done in Java code to make a method call.
The proposed EL MR allows for specifying the method arguments, as well as the invocation of the method in the EL expression itself. The required changes in EL syntax to do this is surprisingly little. All we need to do to is add (what else) a list of arguments in parenthesis to the method calls. For instance, we can added the argument "JAVA" to above JSF fragment:
<h:commandButton action="#{trader.buy('JAVA')}" value="buy"/>
One thing nice about this new syntax is that you can tell immediately that this is a method call, and that the method
takes one parameter of the type String. Furthermore, we also specify the actual argument
to pass to the method when invoked. There is no need to specify the parameter types in the TLD, and there is no hidden arguments in the method
call.
Note in the above code, the EL expression, being a deferred method expression, does not cause the method to be invoked. To actually invoke the method and retrieve the method return value, we can write in a JSP page:
The stock price bought: ${trader.buy('JAVA')}
Very nice!
Included in the EL MR is another feature that is related to method invocation,
namely that of customization of method invocations with the use of custom
ELResolvers. The default behavior for method calls, such as
#{trader.buy('JAVA')} is to look for the method buy, using reflection,
in the bean trader. This default behavior can be altered with custom
ELResovler. A new method invoke is thus added to ELResolver and this
method is used to resolve the evaluation of method calls in expressions,
much like the method getValue is used to resolve the evaluation of
properties in expressions. By providing custom ELResolvers, one can
make "calls" to methods that are not in the bean class. In a sense, this
feature enables the definition and invocation of macros, and can lead to some interesting
applications.
The default behavior for method calls is handled by the class
javax.el.BeanELResolver. Using reflection, it looks up the method in the bean class.
Currently overloaded methods are not supported, and the number of arguments
specified in the EL expression must matched that in the method signature.
This is so because we don't want to specify complicated overload resolution
rules in the EL specification.
However, the method ELResolver.invoke has a paramTypes argument that can be
used to specify the formal parameter types for the method. If this argument
is non-null, then the method with the same name and parameter types will be
selected for invocation. Although the EL syntax does not allow the
specification of parameter types in the method call, it can be done quite
easily with an extended syntax. Borrowing from Javascript (I think) one
can write, for instance
#{trader['buy(java.lang.String)']('JAVA')}
to indicate a call to the method buy with String argument. This is
currently not included in the MR, but if there are enough interest, it can
be considered for the next version of the specification.
The source for the changes to EL api and implementation can be found from Unified Expression Language project. The basic functionalities have been implemented. The area that needs further work is in the overloaded method resolution, and performance.
Posted at 10:42AM Feb 03, 2009 by kchung in Sun | Comments[5]
Native PHP in Glassfish with jsr223
Previously, Ludo and Arun described how to run PHP 5 on GlassFish using Quercus, see here and here. However, it is also possible to invoke the native PHP engine on Glassfish, using jsr223 and a PHP bridge. The following steps should work on Sparc Solaris 10.
- Download script.jar and drop it into <glassfish>/lib.
- Download libphp5-5.0.1-sparc-S2.so, save it as libphp5.so and drop it into <glassfish>/lib.
- Download phptest.war and deploy in Glassfish.
- Run the php.
Of course you can run your php program similarly, just be sure to copy the php servlet mapping into your web.xml.
I built these two files from a Sun internal repository for Jsr223, there may be binaries available publicly, but I can't seem to find them.
Note that version that libphp5.so is 5.0.1, and I have only built it on the Sparc Solaris 10.
It'll be interesting to compare the performance for running PHP on Glassfish, using Quercus and using native PHP. It would also be interesting to compare the performance of Glassfish+PHP with Apache+PHP.
Posted at 03:37PM Feb 15, 2008 by kchung in Sun |
Speed up JSP compilations in GlassFish with JSR 199 Java Compiler Interface
A frequent complaint about web application development is the speed (or lack of) of compiling JSP pages, and a major portion of JSP compilation time is spent in compiling the generated Java files.
In GlassFish, Java compilations are handled with ant, and for reasons I won't get into now, with fork option as the default. This really slow down the compilation.
The reason for using ant to invoke javac is that there is no standard API for invoking it. Well, not until now, that is. JSR 199, Java Compiler API, is now part of Mustang, and starting with b11, GlassFish now supports it for JSP compilations!
To turn on JSR 199 support, take the following steps.
- Use Java SE 6 (code name Mustang) in GlassFish. To do that, the file asenv.conf in ${GF_HOME}/config/asenv.conf needs to be edited to set AS_JAVA to point to Mustang, before starting the appserver.
- Download jasper-jsr199.jar and drop it into ${GF_HOME}/lib. This jar provides the code in jasper that invokes Mustang for java compilations.
The performance gain for using JSR1 199 API is amazing! Preliminary measurement shows an order of magnitude improvement in raw Javac compilation speed, and a 3.5X improvement in overall execution when running JSP TCK tests!
With JSR 199 support in Jasper, the generated Java files and the generated class files are both kept in memory, avoiding unnecessary disk I/Os. The fact that the class files are actual byte arrays makes bytecodes processing (such as SMAP generation and bytecode preprocessing) and class loading much more efficient, as they can all be done in memory.
One other performance work that I haven't done yet is to cache the system jars used in java compilations. Doing this would effectively create a compiler server for the web container. Since this may also have scalability and usability issues, I'll need to experiment to see if this effort is worthwile.
Posted at 02:00PM Jul 31, 2006 by kchung in Sun | Comments[2]
Backward Compatibility of Gassfish with JSF 1.0 Applications
One of the goals of JSP 2.1 is to provide a unified expression language (EL) for JSP and JSF. One key feature of the unified EL is the introduction of deferred expressions. Deferred expressions was first used in JSF 1.0, which used the syntax #{...} to represent a deferred expression. The same syntax is used in JSP 2.1, to ease migration of JSF 1.0 and JSF 1.1 applications to JSF 1.2, bundled in Glassfish.
Additionally, it is imperative that a JSF 1.0 applications can be deployed without modification in Glassfish. A JSF 1.0 application typically runs with JSP version 2.0 or earlier. In JSP 2.0, specifying a "#{...}" as a tag attribute has no special meaning, and the literal string is passed to the tag handler without any processing by the container. In contrast, in JSP 2.1, the compiled version of "#{...}" is passed to the tag handler. To maintain backward compatibility, the JSP container in Glassfish must handle "#{...}" in a JSF 1.0 application as a literal.
Fortunately for us, there is a required "jspversion" tag in the tag library descriptor (TLD) for a tag handler. Based on jspversion in the TLD, the container can then decide to either compile the deferred expression, or to pass the string unchanged.
All this has been working in Glassfish up to build 32 (the one the appserver 9.0 beta was based). Unfortunately, a regression was introduced in b34 which causes the container to (wrongly) issue an error when encountering "#{...}" in a tag attribute. This has been fixed b36.
Posted at 03:52PM Feb 01, 2006 by kchung in Sun |
JSPWiki and GlassFish
Servlets and JavaServer Pages are nothing new, but they are still important components for building web applications. Since they are part of Java EE, applications built with them are completely portable across Java EE containers. JSPWiki is the latest example that I ran across.
JSPWiki is a WikiWiki engine built around servlets and JSPs. It uses AS8.1 for the development. Just out of curiosity, I downloaded a version and installed it with GlassFish, and it just worked!
The intallation cannot be any simpler. After I unzipped the downloaded files, I copied JSPWiki.war to GlassFish's autodeploy directory. I then used the URL http://localhost:8080/JSPWiki/install.jsp to set up the initial configurations (specfying the base Wiki URL, file storage and log files etc.). After I restarted GlassFish, the Wiki page (I used the default http://localhost:8080/JSPWiki) was ready for use. I was able to create and edit pages with links.
JSPWiki is an active open source project and people are busy adding plugins, filters and other functionalities. One feature I like is its simplicity: plain files are used for storage, though there other PageProvider (such as one using mySQL) that are contributed.
I'll play with it more and blog more about it later.
Posted at 03:36PM Dec 16, 2005 by kchung in Sun | Comments[1]