Wednesday, July 9, 2008

VisualVM Included in Java SE 6 Update 7

Luis-Miguel Alventosa announced exciting news: VisualVM 1.0 is now being included in Sun's Java SE 6 implementation as of Update 7. His announcement is available in his blog. VisualVM is a highly useful tool because it consolidates many command-line performance and diagnostic tools that were previously available as separate, non-visual tools in previous versions of Sun's JDK.

I was happy to see Sun include native JAXB support and native annotations processing support in Java SE 6 and even wrote an article for OTN about that. Like VisualVM, JAXB was available for separate download before its inclusion in Java SE 6, but having it integrated in the JDK provided several benefits. Similarly, having a platform JMX agent (introduced in J2SE 5) was also significantly more convenient than using a separate JMX implementation. I expect to realize similar benefits from having VisualVM downloaded as part of the JDK. There is no concern about downloading or configuring VisualVM separately and it can be run simply as %JAVA_HOME%/bin/jvisualvm or $JDK_HOME/bin/jvisualvm (assuming that JAVA_HOME is defined as an environment variable pointing to your JDK 6 Update 7 installation). Because many of us have that directory in our path anyway for convenient use of java, javac, xjc, jconsole, and many other commonly used Java tools, this is especially convenient.

Tuesday, July 8, 2008

NetBeans: Jersey and Tomcat

In my blog entry Project Jersey and Java-Based REST, I used several screen snapshots and some text to illustrate how NetBeans 6.1 can be used with Jersey (the JSR-311/JAX-RS reference implementation) to quickly and easily develop RESTful web services from database tables. The process illustrated there takes advantage of the ability of NetBeans 6.1 (which many other IDEs now have as well) to generate JPA-compliant entity classes from source database tables. Similarly, the ability of NetBeans to automatically generate Jersey artifacts for JPA entities was also used and illustrated.

In the referenced blog entry, I did not talk much about the differences of deployment to Tomcat or to GlassFish or other web server. While much of the process is the same regardless of the server used, the JPA persistence.xml file does need to be altered. In this blog entry, I'll focus on the deploying the JPA-backed Jersey-based RESTful web services on Tomcat.

The default persistence.xml file generated as part of the JPA entity generation process (and based on my wizard settings) is shown next:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="SimpleJerseyProjectPU" transaction-type="JTA">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>jdbc/hr</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>


The NetBeans-centric article Getting Started with RESTful Web Services on Tomcat points out in the Configuring the Persistence File section how to change that file for Tomcat. In particular, it recommends changing that file to remove the jta-data-source element, to change the transaction-type attribute of the persistence-unit element to RESOURCE_LOCAL, and to specify JPA implementation-specific provider properties in the file. For my Oracle database using TopLink Essentials, the persistence.xml file now looks like this:


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="SimpleJerseyProjectPU" transaction-type="RESOURCE_LOCAL">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<!-- <jta-data-source>jdbc/hr</jta-data-source> -->
<exclude-unlisted-classes>false</exclude-unlisted-classes>

<properties>
<property name="toplink.jdbc.user" value="hr"/>
<property name="toplink.jdbc.password" value="hr"/>
<property name="toplink.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:ORCL"/>
<property name="toplink.jdbc.driver" value="oracle.jdbc.OracleDriver"/>
</properties>

</persistence-unit>
</persistence>


The previously referenced article also pointed out some other useful changes that I needed to make. For example, I copied the libraries specified (except for Derby because I was using Oracle) in the Copying Libraries to Tomcat section to the appropriate Tomcat directories as specified.

During the NetBeans generation process, the web.xml (WEB-INF) file and the context.xml (META-INF) file are generally taken care of automatically.

With the change to the persistence.xml file and the appropriate libraries copied to the appropriate Tomcat directories, it was easy to use NetBeans' "Test RESTful Web Services" feature to have the newly generated web services automatically deployed (to Tomcat in this case because it was my currently selected server) and have a browser-based client access the deployed web services.




In somewhat related news, I found two recently posted blog entries on REST to be particularly interesting. In REST vs REST, Anthony Goubard differentiates between what he calls "Pure REST" (close attention to HTTP operations GET, POST, PUT, DELETE and the JSR 311 approach) and the "RESTful Way" (more traditional HTTP servlet approach with use of GET and/or POST and URL parameters). Anthony then goes on to delineate problems he sees with the "Pure REST" approach.

The second article is REST Anti-Patterns by Stefan Tilkov. The first two of his eight REST anti-patterns are: 1) Tunneling everything through GET and 2) Tunneling everything through POST. (By the way, Stefan's short entry WS-Dilemma is poignant and worth the brief read.)

What these two interesting and useful blog entries demonstrate is that while many people are choosing REST for their web services approach, there is still much disagreement about what qualifies as REST at all, let alone as an efficient REST approach. Although such differences can be distracting at times, I generally prefer this type of discussion and bantering of ideas because I believe it leads to a Darwinian effect (thanks, Bill, for pointing out the application of this term to software development) in the software industry.

Monday, July 7, 2008

Project Jersey and Java-based REST

Project Jersey is the reference implementation of JSR 311 ("The Java API for RESTful Web Services"). The main page states that Jersey is currently available as an "early access" version and cannot transition to 1.0 until the specification it implements (JAX-RS/JSR-311) receives final approval.

There are several highly useful resources provided to learn how to apply Jersey in Java-based web services, especially in the Project Jersey Community Wiki. The REST Web Services Developers Guide is available in both HTML and PDF formats. This 34-page document introduces basic concepts of REST (Representational State Transfer) and covers how to use Jersey to apply REST. The Jersey Getting Started page shows how to create a simple Hello World style REST-based web service. One thing I found particularly interesting about this is that it uses the Lightweight HTTP Server distributed with Sun's implementation of Java SE 6.

Another useful resource on using Jersey with REST is the Enterprise Java Technology Tech Tip Implementing RESTful Web Services in Java.

If you use the NetBeans IDE, two particularly useful articles on using NetBeans 6.0 with Jersey are Getting Started with RESTful Web Services on GlassFish and Getting Started with RESTful Web Services on Tomcat. In the remainder of this article, I will demonstrate how to use NetBeans 6.1 with Jersey and the Oracle database HR schema to generate a RESTful web service.

SIDE NOTE: I started working on this example before discovering the two NetBeans/Jersey articles related to Tomcat and GlassFish described above. However, even after discovering these articles, I decided that it could be worthwhile to publish this blog entry because I am going to use NetBeans 6.1 (the articles use NetBeans 6.0), I am going to use an external Oracle database, and I am going to add different commentary than that available in the two articles hosted on the NetBeans site. However, because the basic Jersey support seems to be largely the same between NetBeans 6.0 and NetBeans 6.1, I am going to try to not repeat much of what is already available in those articles unless the repetition is necessary to make this blog entry flow more smoothly.

The Jersey distribution can be downloaded, but this step is unnecessary with NetBeans 6.1. The snapshot below (click on snapshots to see larger versions) demonstrates the "Jersey (JSR 311) Libraries" library (and its content JARs) that is available with NetBeans and can be included in a project using Jersey.



NetBeans 6.1 includes a plugin for Jersey. This is shown in the next screen snapshot:



With the Jersey library added to my NetBeans 6.1 project and the plugin installation verified, it is time to start developing a simple Jersey-based web service. For this example, I will be using the Oracle HR database schema. When one runs a SELECT table_name FROM user_tables SQL command in SQL*Plus on this schema, the following tables are shown


TABLE_NAME
------------------------
LOCATIONS
COUNTRIES
DEPARTMENTS
REGIONS
JOB_HISTORY
JOBS
EMPLOYEES


With existing database tables like those shown above, it is trivial to generate Java Persistence API (JPA) entity classes from the database tables in NetBeans 6.1.

The next three screen snapshots indicate how simple it is to generate "Entity Classes from Database," to select appropriate tables from which JPA entity classes should be generated, and to specify a package structure for the generated JPA entity classes.







You may have noticed some tables and generated JPA entities in the above screen snapshots that are not normally in the HR schema. These tables are in my schema because I created them and am using them for something else, but they are not significant for this example.

The next screen snapshot shows the generated JPA entity classes as they appear in the NetBeans 6.1 IDE.



The icons with exclamation points in the middle of red circles indicate classes that do not compile with the current NetBeans compiler classpath settings. To address this, I needed to add the TopLink Essentials (JPA 1.0 reference implementation) library to the project. This library is delivered with NetBeans 6.1, so this is a relatively easy task. The next screen snapshot indicates how the addition of the TopLink Essentials library allows the generated entity classes to build properly.



Thus far, NetBeans 6.1 has done most of the heavy lifting. We have not done anything REST or even Web Service specific, but we do have JPA entity classes generated and corresponding to the database tables we started with. The next step is to let NetBeans 6.1 generate the appropriate Jersey-based artifacts to support RESTful web services access of these newly generated entity classes. The next four screen snapshots show how to generate "RESTful Web Services from Entity Classes," how to select the entity classes from which REST/Jersey artifacts should be generated, which Jersey/REST artifacts are to be generated, and the generation of Jersey-based REST web services in action.









When the steps shown in the screen snapshots immediately above are executed, the Jersey-based web services artifacts shown in the next four screen snapshots are generated or set up.

Converters - Convert Between JPA Entities and Jersey Services


Services - Workhorse Classes for Jersey-based REST Web Services Support


Jersey Libraries Automatically Associated with NetBeans Project


NetBeans RESTful Web Services


NetBeans 6.1 has done most of the work to go from database tables to JPA entities and from JPA entities to RESTful Web Services. NetBeans does even more for us by providing an easy testing and monitoring mechanism. By right-clicking on the "RESTful Web Services" icon shown in the last screen snapshot (in NetBeans' Project window) and selecting , a web browser comes up with a basic "Test RESTful Web Services" web page that can be used to test and monitor the running REST-based web services. The next screen snapshot shows a snippet of this using a REST query for employee with employee ID of 170.



There is much to look at in the web page for testing, but my focus here is on the simplicity of the REST-style URL (see Resource toward top of web page), the tabs at the bottom that allow you to see the "raw" XML in addition to the useful Tabular View and HTTP Monitor tabs, and the URL for the WADL (see top left corner).

In this blog, I used NetBeans to create the RESTful web services from JPA entity classes that were generated by NetBeans from an Oracle database schema. I also performed simple testing of my newly generated RESTful web services using NetBeans' automatic support. I intend to follow up with additional blog entries in which I use non-NetBeans clients to contact these RESTful web services.

Wednesday, July 2, 2008

Simple Spring HTTP Remoting Example

I am using this blog entry to demonstrate by simple example the use of the Spring Framework's HTTP Remoting. There are numerous online resources on this subject, so my intention here is to provide an extremely simple but complete demonstration of using Spring's HTTP Remoting with non-browser clients.

The Spring approach to HTTP Remoting allows clients to communicate with the Spring-hosted server code via HTTP without the client code requiring any knowledge of HTTP being used. Instead, the client Java code only "sees" normal business-related Java objects (usually interfaces) rather than HTTP-specific objects.

Spring HTTP Remoting generally requires Spring and Java on both the server side and client side. However, if those two requirements can be met, Spring HTTP Remoting is easily applied.

The following steps allow HTTP communication between Spring-hosted clients and servers. After first briefly outlining the steps, I'll then delve into them in more detail (including code samples).


  1. Create or use an existing Spring bean that typically implements a Java interface.

    This is nothing special to HTTP remoting and is the same step you'd need to take to do most things in Spring (a notable exception is Spring JDBC that does not require any Spring beans to be used).


  2. Create the Spring XML configuration file for associating the bean created in step #1 with a Spring application context.

    As with Step #1, this XML file is nothing particular to Spring HTTP Remoting, but is instead common to nearly all Spring Framework wiring and configuration.


  3. Create or add to web.xml file.

    This third step is the first step that is more particular to Spring HTTP Remoting, but is still generally applicable with Spring MVC framework. This step includes adding the servlet class and URL mappings as one usually uses with Java EE servlets and JavaServer Pages. The most important part of this step is to specify the Spring DispatcherServlet. An optional "link" is also provided in this web.xml file to a context config location where one or more Spring XML application context files are located and used.


  4. Create the Spring-specific servlet context file.

    This XML file looks a lot like a "normal" Spring application context XML configuration file, but its name is prescribed by the convention of servlet name followed by a hypen and the word servlet. In other words, if the servlet was called "somewebthing" in the web.xml file, this Spring servlet configuration file would be called somewebthing-servlet.xml. This file contains the configuration for the HttpInvokerServiceExporter (the piece of this that is particular to the HTTP Remoting covered in this blog entry) and URL mapping information.


  5. Test!

    Although the simple client will be writting without HTTP in mind and will appear to only be using Java objects, it will actually be invoking the service via HTTP. This will be "proven" by running the client without the service deployed and watching for the resulting HTTP error code.




I'll now move onto demonstrating the above steps in greater detail and attempt to illustrate them concretely with code samples.

Step #1: The Bean and Its Interface

This step is no different than defining Java classes and interfaces they implement for use with Spring. The following code listings show the interface (StateCapitalServiceIF) and the implementing class (StateCapitalService) used for this example.

--- StateCapitalServiceIF.java ---

package examples.springhttp;

import java.io.Serializable;

/**
* The State Capital Service interface that the client will use to access
* server-side functionality via HTTP.
*/
public interface StateCapitalServiceIF extends Serializable
{
/**
* Provide capital of state whose name is provided.
*
* @param stateName Name of state whose capital is desired.
* @return Capital of the specified state; null if not found.
*/
public String getCapital(final String stateName);
}


--- StateCapitalService.java ---

package examples.springhttp;

import java.util.Map;

/**
* Implementation of functionality to be run after being called by client via
* HTTP.
*/
public class StateCapitalService implements StateCapitalServiceIF
{
Map statesAndCapitals = null;

public StateCapitalService()
{
}

/**
* Set my states to state capitals mapping.
*
* @param statesAndCapitals States to state capitals mapping.
*/
public void setStatesAndCapitals(final Map statesAndCapitals)
{
this.statesAndCapitals = statesAndCapitals;
}

/**
* Provide capital of state whose name is provided.
*
* @param stateName Name of state whose capital is desired.
* @return Capital of the specified state; null if not found.
*/
public String getCapital(final String stateName)
{
return this.statesAndCapitals.get(stateName);
}
}



Step #2: Spring Application Context Configuration File

I like to keep Spring's HTTP-specific configuration separate from the bean's XML configuration. Therefore, the bean's configuration is exactly like one would see normally with Spring. To configure the StateCapitalService class above, the following configuration is used:

--- spring-http-config.xml ---

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<util:map id="statesCapitalsMap">
<entry key="Alabama" value="Montgomery" />
<entry key="Alaska" value="Juneau" />
<entry key="Arizona" value="Phoenix" />
<entry key="Arkansas" value="Little Rock" />
<entry key="California" value="Sacramento" />
<entry key="Colorado" value="Denver" />
<entry key="Connecticut" value="Hartford" />
</util:map>

<bean id="stateCapitalService"
class="examples.springhttp.StateCapitalService"
p:statesAndCapitals-ref="statesCapitalsMap" />

</beans>


So far, nothing specific to HTTP Remoting has been done. In fact, the bean, its interface, and its XML application context configuration could all be run by a normal Java SE class like the one shown below:

--- MainServiceAppContext.java ---

package examples.springhttp;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* Demonstrates how Spring bean can be used without any HTTP involvement.
*/
public class MainServiceAppContext
{
public static void printStateInfo(
final StateCapitalServiceIF stateCapitalMapper,
final String state)
{
System.out.println(
"The capital of " + state + " is "
+ stateCapitalMapper.getCapital(state));
}

/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
final ApplicationContext context =
new ClassPathXmlApplicationContext(
"examples/springhttp/spring-http-config.xml" );
StateCapitalServiceIF stateCapitalMapper =
(StateCapitalServiceIF) context.getBean("stateCapitalService");
printStateInfo(stateCapitalMapper, "Alabama");
printStateInfo(stateCapitalMapper, "Colorado");
}
}


Step #3: The web.xml File

This web.xml file is familiar to anyone who has developed a Java EE web application. The web.xml used in this example is shown next.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>
Simple Spring HTTP Remoting Example
</display-name>

<description>
This is meant as an extremely simple example of using Spring's HTTP
Remoting capability.
</description>

<servlet>
<servlet-name>statesCapitals</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>statesCapitals</servlet-name>
<url-pattern>/statesCapitals</url-pattern>
</servlet-mapping>

<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/examples/springhttp/spring-http-config.xml</param-value>
</context-param>

</web-app>


Step #4: The Servlet Context Configuration File

Because the servlet in this example is named "statesCapitals," a Spring servlet configuration file named statesCapitals-servlet.xml needs to be provided. It is shown next:

--- statesCapitals-servlet.xml ---

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<bean id="httpStateCapitalService"
class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"
p:service-ref="stateCapitalService">
<property name="serviceInterface">
<value>examples.springhttp.StateCapitalServiceIF</value>
</property>
</bean>

<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/statesCapitals">httpStateCapitalService</prop>
</props>
</property>
</bean>

</beans>


Step #5: Testing It

We need to configure the client to communicate via HTTP with our server-side application. The configuration for this is contained in spring-http-client-config.xml for this example and is shown next:

--- spring-http-client-config.xml ---

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">

<bean id="stateCapitalProxyService"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl">
<value>http://localhost:8080/SpringHTTPExample/statesCapitals</value>
</property>
<property name="serviceInterface">
<value>examples.springhttp.StateCapitalServiceIF</value>
</property>
</bean>

</beans>


The client code that uses the above XML to bootstrap a Spring container and call the server-side code via HTTP is in the class HttpClient and that code is shown next:

--- HttpClient.java ---

package examples.springhttp.client;

import examples.springhttp.StateCapitalServiceIF;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
* This class demonstrates a client of a Spring HTTP-exposed service and shows
* how the client interacts with the server as if using normal Java objects
* rather than using anything HTTP specific.
*/
public class HttpClient
{
public static void printStateInfo(
final StateCapitalServiceIF stateCapitalMapper,
final String state)
{
System.out.println(
"The capital of " + state + " is "
+ stateCapitalMapper.getCapital(state));
}

public static void main(final String[] arguments)
{
final ApplicationContext context =
new ClassPathXmlApplicationContext(
"examples/springhttp/client/spring-http-client-config.xml");
final StateCapitalServiceIF stateCapitalService =
(StateCapitalServiceIF) context.getBean("stateCapitalProxyService");
printStateInfo(stateCapitalService, "Colorado");
printStateInfo(stateCapitalService, "Alabama");
}
}


When the server-side code is built into a WAR and deployed to Tomcat or other web server, the above client will connect to it successfully and print out the capitals of Alabama and Colorado as shown in the next screen snapshot:



If the server-side application is undeployed or the web server is turned off, the client prints a 404 ("Not Found") HTTP status code indicating it is not available and proving that HTTP is being used. This is shown in the next screen snapshot.



The Packaging

I have displayed the contents of all the files above, but the packaging of them can be a little tricky. This section shows the contents of various JARs and the WAR I used to run the above examples.

--- SpringHTTPExample.war ---
This is the WAR file I deployed to Tomcat:

102 Thu Jul 03 23:25:54 MDT 2008 META-INF/MANIFEST.MF
1218 Thu Jul 03 23:13:42 MDT 2008 WEB-INF/web.xml
1505 Thu Jul 03 23:25:56 MDT 2008 WEB-INF/lib/SpringHTTPExample-web.jar
52915 Thu Jul 03 23:25:56 MDT 2008 WEB-INF/lib/commons-logging.jar
2832933 Thu Jul 03 23:25:56 MDT 2008 WEB-INF/lib/spring.jar
385822 Wed Jan 09 13:24:06 MST 2008 WEB-INF/lib/spring-webmvc.jar
1099 Thu Jul 03 22:33:04 MDT 2008 WEB-INF/examples/springhttp/spring-http-config.xml
1143 Thu Jul 03 23:25:42 MDT 2008 WEB-INF/statesCapitals-servlet.xml


In the above WAR, three of the JARs in the WEB-INF/lib are Spring-provided. Besides those, the remaining content of the WAR consists simply of the web.xml file shown above, the statesCapitals-servlet.xml file shown above, the spring-http-config.xml file shown above, and a JAR file called SpringHTTPExample-web.jar, whose contents are shown next.

--- SpringHTTPExample-web.jar ---

102 Thu Jul 03 23:25:54 MDT 2008 META-INF/MANIFEST.MF
1011 Thu Jul 03 23:25:54 MDT 2008 examples/springhttp/StateCapitalService.class
205 Thu Jul 03 23:25:54 MDT 2008 examples/springhttp/StateCapitalServiceIF.class


The contents of the JAR above consist simply of the bean class and the interface it implements, both of which are shown above.

--- SpringHTTPClient.jar ---
The contents JAR used to test the HTTP-exposed service are shown now:

102 Thu Jul 03 23:25:54 MDT 2008 META-INF/MANIFEST.MF
205 Thu Jul 03 23:25:54 MDT 2008 examples/springhttp/StateCapitalServiceIF.class
1618 Thu Jul 03 23:25:54 MDT 2008 examples/springhttp/client/HttpClient.class
954 Thu Jul 03 23:25:54 MDT 2008 examples/springhttp/client/spring-http-client-config.xml


The above client JAR includes the compiled version of the client class shown above along with the spring-http-client-config.xml configuration file shown above. Perhaps the most interesting thing to note here is that the interface class included in the server JAR also needs to be in the client JAR. This makes sense, of course, because it is that interface the client code uses as a proxy to the server side.

Conclusion

In this blog entry, I have included all the code (Java and XML) necessary to build and run a simple example that uses and illustrates Spring's HTTP Remoting capabilities. I did not cover every nuance of this feature and did not explicitly discuss some of the associations between various configuration files. There are several good resources on Spring's HTTP Remoting that do this. I instead attempted to illustrate complete code for a simple Spring HTTP Remoting example without referencing work on similar Spring remoting solutions. (Because Spring treats remoting very consistently, many good books and tutorials cover HTTP support with references to the other protocols supported.) I am including some references to these other resources related to Spring HTTP remoting below.

Other Resources

* Section 17.4 ("Exposing Services Using HTTP Invokers") of Spring Framework 2.5 Reference Manual

* Best of Both Worlds Remote Services with Spring HTTP Invoker

* A Case for Lightweight Remoting (Part 2): Spring to the Rescue

Tuesday, July 1, 2008

Big News in the OpenLaszlo Community: 4.1 and 500k

There have been two major OpenLaszlo announcements in the last two days (yesterday and today) as recorded at http://swik.net/OpenLaszlo. It was announced today that one-half million copies of OpenLaszlo have been downloaded.

While 500,000 downloads is a significant milestone for the OpenLaszlo project, an even bigger announcement for many of us was made a day earlier when it was announced that OpenLaszlo 4.1 is now available and is the recommended released of OpenLaszlo. This is exciting news for anyone who has been waiting for OpenLaszlo's DHTML support to move out of beta Frankly, I was surprised at this release because I assumed that it would still be a while before 4.1's release due to recent interest in OpenLaszlo support of Flash Player 9.

Although the big news associated with OpenLaszlo 4.1's release is its DHTML support, it is also worth noting that "preliminary" support for Flash Player 9 has also been included. Other welcome news includes the observation that OpenLaszlo 4.1 addresses over 800 bugs. The current download page indicates the particular web browser/operating system combinations on which OpenLaszlo 4.1 has been qualified.

The OpenLaszlo 4.1 Release Notes contain additional details and information regarding this release. For example, these Release Notes point out that the button for compiling using preliminary Flash 9 support has been removed from the developer console. However, an OpenLaszlo developer can still choose to compile to Flash 9 using the
lzr=swf9 Laszlo Runtime parameter. The Release Notes also link to the document "Runtime Differences," which documents runtime differences between DHTML and SWF/Flash.

Another piece of recent good news for OpenLaszlo applications is the announcement of SWF searchability. One of the common complaints against Flash-based applications is their reduced ability to support engine optimization. A common approach has been to include text in the HTML "wrapper" pages of Flash applications, but this new approach should provide developers of Flash applications with much greater power and flexibility in search engine support. For now, this increased Flash searchability seems limited to Google and Yahoo! search engines, but my guess is that these two are by far the most heavily used of the search engines.

Monday, June 30, 2008

The Value of Named Parameters in JPA QL

In my article Basic Java Persistence API Best Practices, I wrote that because JPA is the result of good ideas from many previous technologies (Hibernate, JDBC, JDO, etc.), it follows that many of the best practices associated with these inspiring technologies can and should be applied to JPA. I used named and positional parameters as an example of this.

The interesting thing about JDBC's PreparedStatement is the fact that, out of the box, the JDBC standard PreparedStatement does not support named parameters. Rather, the PreparedStatement supports placeholders in the SQL syntax that are "populated" via set methods that provide the index of the ? being replaced (counting from left to right).

In order to make code more readable and easier to maintain, many people have tried to workaround the PreparedStatement's positional parameter binding approach. For example, I have seen cases where developers have made the numeric instances Java constants with names that are more readable than the numeral itself. More elegant solutions for using a named parameter type approach have been created to more easily enable "named" parameters. For example, Adam Crume introduces a class called NamedParameterStatement in the JavaWorld article Named Parameters for PreparedStatement. Perhaps even better known is the Spring Framework's support for the NamedParameterJdbcStatement (part of Spring's extensive JDBC support). Finally, Oracle has provided an Oracle-specific JDBC extension that allows named parameters to be specified and used with the OraclePreparedStatement when using an Oracle JDBC driver.

The rising popularity of being able to used named parameters in addition to ordinal parameters is also showcased by Oracle's support for named parameters in JDBC calls to PL/SQL and in IBM's Informix Dynamic Server (IDS).

The JPA contributors recognized the usefulness and desirability of named parameters and JPA Query Language has supported them since JPA's inception. JPA Query Language supports input parameters that are specified with a colon and the parameter name. Then, as demonstrated in the article Standardizing Java Persistence with the EJB3 Java Persistence API, this input parameter can be set by calling the Query.setParameter(---) method.

The JPA 1.0 specification covers named parameters in section 3.6.3. This section indicates how to use named parameters and points out that named parameters are only portable across JPA providers for JPA Query Language statements (not for native queries).

In the case of JPA, hindsight is 20/20. JPA was able to leverage named parameter binding in JPA Query Language statements from the beginning. This allows JPA developers to take advantage of a feature that has been proven to be beneficial many times over and has led to custom implementations when named parameter support is not built into the language or framework.

Friday, June 27, 2008

OpenLaszlo and SpketIDE

SpketIDE is a useful IDE for developing OpenLaszlo applications. SpketIDE provides many useful OpenLaszlo editing functions beyond the simple color syntax support available with NetBeans 6.1 (as demonstrated in Flex and OpenLaszlo in NetBeans 6.1 Beta) or JEdit (as demonstrated in Using JEdit with OpenLaszlo and Flex) or other XML-cognizant editors.

The main SpketIDE Laszlo Editor page demonstrates many of the useful features Spket provides for OpenLaszlo development. Of course, there is color syntax highlighting support, but there is also support for more advanced features such as different types of code completion and occurrence marking. I like having the Laszlo documentation available in the editor as an added convenience because I otherwise find myself spending a lot of time flipping back and forth between my editor and the LZX Reference Manual.

According to the Spket 1.6.12 Downloads page, there is no charge for SpketIDE for non-commercial use. Currently (late June 2008), the license cost for a single license for commercial use is less than $30 USD. The SpketIDE FAQ also provides information on how to use SpketIDE with OpenLaszlo specifically.

I used SpketIDE to write the code for my example of writing an RSS Reader with OpenLaszlo and a screen snapshot of that code in SpketIDE is shown next (click on the image to see a larger version).



This snapshot demonstrates the Project Explorer, the Outline, Code Snippets (with Components opened up), the Lz Documentation window, and, of course, the main code editing window with color coded syntax.

SpketIDE is a useful editor for OpenLaszlo developers that is simple but powerful, easy to use, and has the potential to increase OpenLaszlo developer productivity.