Wednesday Aug 10, 2011

TOTD #169: Multi-catch - Using Java 7 in Java EE 6/GlassFish

Project Coin introduces a small set of changes to the Java language making your everyday programming easier. The TOTD #167 explained how to use Automatic Resource Management particularly for a Java EE 6 application. The TOTD #168 showed how to use "String switch statement" for a RESTful Web service. This Tip Of The Day (TOTD) will explain a scenario where multi-catch can be used in Java EE 6 applications.

Consider the following piece of code:

protected void doPost(HttpServletRequest request, HttpServletResponse response){
    PrintWriter out = null;
    try {
        response.setContentType("text/html;charset=UTF-8");
        out = response.getWriter();
        out.println("<html><head><title>Servlet TestServlet</title></head>");
        out.println("<body>");
        out.println("<h1>Sending email from " + request.getContextPath () + "</h1>");
        
        for (Part p : request.getParts()) {
            // save the parts locally
            System.out.println(p.getName() + " saved");
        }  
       Message message = new MimeMessage(session);        message.setFrom(new InternetAddress(from));        InternetAddress[] address = {new InternetAddress(to)};         message.setRecipients(Message.RecipientType.TO, address);         message.setSubject("File upload successful.");         message.setSentDate(new Date());         message.setText("File has been successfully saved.");         Transport.send(message);
        out.println("</body>");         out.println("</html>");     } catch (ServletException ex) {         Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);     } catch (MessagingException ex) {         Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);     } catch (IOException ex) {         Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);     } finally {         out.close();     } }


If you are familiar with Java EE 6 then you'll understand that this fragment is from a Servlet responding to a POST request. This fragment receives a multi-part message such as a file, saves it locally, and then sends a confirmation email. The fields used for sending an email are initialized in the "init" method of the Servlet (not shown here for brevity).

If you notice then there are 3 "catch" blocks and each one of them is executing the same code, printing a log message. Using JDK7 multi-catch block, the different "catch" blocks can be combined together and rewritten as (highlighted in bold):

    out.println("</body>");
    out.println("</html>");
} catch (ServletException | MessagingException | IOException ex) {
    Logger.getLogger(TestServlet.class.getName()).log(Level.SEVERE, null, ex);
} finally {            
    out.close();
}

If you have configured NetBeans 7.0.1 for the JDK7 Source/Binary format then it will show you a hint as shown below:

The catch parameter of a multi-catch clause is regarded as implicitly final. An explicit final modifier will be redundant and one more way JDK7 enables more concise syntax.

How are you using JDK7 features in Java EE 6 applications ?

 

Sunday Aug 07, 2011

TOTD #168: String switch statement - Using Java 7 in Java EE 6/GlassFish


Project Coin introduces a small set of changes to the Java language making your everyday programming easier. TOTD #167 explained Automatic Resource Management (ARM) and this Tip Of The Day (TOTD) will explain how to use Strings in switch statements.

Prior to JDK7, switch statement worked on byte, short, char, and int primitive data types and enum. It took us about 16 years to realize that java.lang.String is also a constant and add it to the list of data types supported by a switch statement :-)

Consider the following RESTful endpoint that responds with the color of a fruit:

@Path("fruits")
public class FruitResource {

@GET
@Produces("application/json")
@Path("{name}")
public String getJson(@PathParam("name")String name) {
if (name.equals("apple") || name.equals("cherry") || name.equals("strawberry"))
return "Red";
else if (name.equals("banana") || name.equals("papaya"))
return "Yellow";
else if (name.equals("kiwi") || name.equals("grapes") || name.equals("guava"))
return "Green";
else if (name.equals("clementine") || name.equals("persimmon"))
return "Orange";
else
return "Unknown";
}
Using JDK 7's String switch statement this code can be easily re-written as:

@Path("fruits")
public class FruitResource {

@GET
@Produces("application/json")
@Path("{name}")
public String getJson(@PathParam("name")String name) {
switch (name) {
case "apple":
case "cherry":
case "strawberry":
return "Red";
case "banana":
case "papaya":
return "Yellow";
case "kiwi":
case "grapes":
case "guava":
return "Green";
case "clementine":
case "persimmon":
return "Orange";
default:
return "Unknown";
}
}

The number of characters is pretty similar (669 using switch and 674 without) but the code is much more readable, no chained if-else statements, and slightly better performance (not measured). Couple of things to keep in mind:
  • Check for null before the switch
  • Check for different case letters before the switch

NetBeans 7.0.1 provide a hint if you have a chained if-else statement to take advantage of the JDK7 features. Have you downloaded it yet ? Check out screencast #35 highlighting Project Coin features in NetBeans.

NetBeans 7.0.1 provide complete tooling around JDK7 and GlassFish 3.1.1 allow you to leverage JDK7 features in your Java EE 6 applications.

How are you using JDK7 features in your Java EE 6 applications ?


Thursday Aug 04, 2011

TOTD #167: Automatic Resource Management or try-with-resources - Using Java 7 in Java EE 6/GlassFish


Java 7 is now available, NetBeans 7.0.1 provide complete tooling around it, and GlassFish 3.1.1 allow you to leverage JDK7 features in your Java EE 6 applications. This Tip Of The Day (TOTD) will explain a new feature introduced in JDK7 and how it can be used to simplify your Java EE 6 application code.

Automatic Resource Management (ARM) or try-with-resources is one of the functionality coming from Project Coin as part of Java 7. It simplifies working with external resources such as JDBC connection/statement and xxxInput/OutputStream which need to be explicitly closed in case of an error or successful completion of a code block.

The code originally published in TOTD #164 is given below:

@javax.annotation.PostConstruct
void startup() {
   Connection c = null;
   Statement s = null;
   try {
     InitialContext ctx = new InitialContext();
     DataSource ds = (DataSource)ctx.lookup("jdbc/__default");
     c = ds.getConnection();
     s = c.createStatement();

// invoke SQL here

   } catch (SQLException ex) {
     System.err.println("ouch!");
   } catch (NamingException ex) {
     System.err.println("ouch!");
   } finally {
     try {
       if (s != null)
         s.close();
       if (c != null)
         c.close();
     } catch (SQLException ex) {
       System.err.println("ouch!");;
     }
   }
}
This is a lot of boilerplate code, couple of specific points to note here:
  • Because Connection and Statement need to be closed in "finally" block, they need to be declared outside of the "try" block.
  • "s.close()" and "c.close()" can further throw an SQLException and so there is a nested exception in the "finally" block.
 This code can also be rewritten as:
@Resource(name="jdbc/sample")
DataSource ds;

@javax.annotation.PostConstruct
void startup() {
   Connection c = null;
   Statement s = null;
   try {
     c = ds.getConnection();
     s = c.createStatement();

     // invoke SQL here

   } catch (SQLException ex) {
     System.err.println("ouch!");
   } finally {
     try {
       if (s != null)
         s.close();
       if (c != null)
         c.close();
     } catch (SQLException ex) {
       System.err.println("ouch!");;
     }
   }
}
It still has tons of boilerplate code. This can be easily simplified using JDK 7 Automatic Resource Management by changing the code to:

@Resource(name="jdbc/sample")
DataSource ds;

@javax.annotation.PostConstruct
void startup() {
try (Connection c = ds.getConnection();
     Statement s = c.createStatement())

       // invoke SQL here
     } catch (SQLException ex) {
       System.err.println("ouch!");;
     }
   }
}

The resources defined in the "try" block are automatically closed as they get out of scope and there is no boilerplate code here. The code is much more semantically readable and contains 285 characters instead of 629 in the first version.

NOTE: The code fragments in this blog are updated because throwing a checked exception from a @PostConstruct method is not permitted by the Managed Beans specification. See the comments below for more detailed discussion.

How does this all work under the hood ?

A new java.lang.Autocloseable API has been added to the platform which has a single "close()" method that automatically closes the resource. The java.io.Closeable extends this new API ensuring that xxxInputStream and xxxOutputStream are candidates for ARM. Any resource implementing this interface can be used for ARM so if there are any custom resources in your project then they can leverage this functionality as well.

NetBeans 7.0.1 provide hints to take advantage of JDK7 features. Have you downloaded it yet ? Check out screencast #35 highlighting Project Coin features in NetBeans.

How are you using JDK7 features in your Java EE 6 applications ?

Monday May 30, 2011

TOTD #163: Application-scoped Resources in GlassFish using NetBeans

A globally defined resource such as JDBC connection pool, JDBC resource, JavaMail resource, Connector connection pools etc. in an application server is available globally to all the applications. This can cause resource starvation for a particular application due to usage by other applications. The application-scoped resources solves that problem by bundling the resource definitions along with the application. These resources are then created as part of the deployment and made available to the application, without the need for an explicit deployment script. These resources are automatically destroyed when the application is undeployed. These resources cannot be accessed from other applications and scoped to the deployed application only.

Jagadish blogged about app-scoped resources here. More details about this feature can be found in the Oracle GlassFish Server Online Docs.

This Tip Of The Day (TOTD) explains how to create application-scoped resources using NetBeans and deploy such an application in GlassFish.

  1. In NetBeans, create a Java EE 6 Web project by right-clicking in the “Projects” pane and selecting the category "Java Web", "Web Application". Name the project “AppScopedResources”. Click on “Next>” and take all the defaults.
  2. Right-click on the newly created project, select “New”, “Other...”, scroll to “GlassFish” and select “JDBC Resource”.

  3. Select “Create New JDBC Connection Pool” and take the default “JNDI Name” (or feel free to edit it) and click on “Next”.
  4. Click on “Next” as we don't need any additional properties.
  5. Change the “JDBC Connection Pool Name” to “myConnectionPool” and choose from an existing database connection as shown:



    The database connection in your IDE may be different. Click on “Next>”.
  6. Enter the username/password credentials and click on “Finish”.



    This generates “glassfish-resources.xml” under the newly created “Server Resources” tree in the “Projects” pane. The file looks like:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
    <resources>
      <jdbc-resource enabled="true" jndi-name="jdbc/myDatasource" object-type="user" pool-name="myConnectionPool">
        <description/>
      </jdbc-resource>
      <jdbc-connection-pool allow-non-component-callers="false" associate-with-thread="false" connection-creation-retry-attempts="0" connection-creation-retry-interval-in-seconds="10" connection-leak-reclaim="false" connection-leak-timeout-in-seconds="0" connection-validation-method="auto-commit" datasource-classname="org.apache.derby.jdbc.ClientDataSource" fail-all-connections="false" idle-timeout-in-seconds="300" is-connection-validation-required="false" is-isolation-level-guaranteed="true" lazy-connection-association="false" lazy-connection-enlistment="false" match-connections="false" max-connection-usage-count="0" max-pool-size="32" max-wait-time-in-millis="60000" name="myConnectionPool" non-transactional-connections="false" pool-resize-quantity="2" res-type="javax.sql.DataSource" statement-timeout-in-seconds="-1" steady-pool-size="8" validate-atmost-once-period-in-seconds="0" wrap-jdbc-objects="false">
        <property name="URL" value="jdbc:derby://localhost:1527/sun-appserv-samples"/>
        <property name="serverName" value="localhost"/>
        <property name="PortNumber" value="1527"/>
        <property name="DatabaseName" value="sun-appserv-samples"/>
        <property name="User" value="APP"/>
        <property name="Password" value="APP"/>
      </jdbc-connection-pool>
    </resources>
    



    If this application is deployed as is then the JDBC connection pool and resource are created in the global scope and are shared with other applications.
  7. Move “glassfish-resources.xml” to the “WEB-INF” directory. This ensures that the resources are created in the application-scope only.
  8. Right-click and select “Deploy”. In the “Services” pane, expand the GlassFish tree, “Resources”, “JDBC”, “JDBC Resource” and “Connection Pools”. This tree shows all the global JDBC connection pools and resources. The resources created as part of the application deployment are not shown here, as expected.
  9. In a shell, give the following commands:
    ~/tools/glassfish/3.1/glassfish3 >./bin/asadmin list-applications --resources
    AppScopedResources <web>
      java:app/jdbc/myDatasource <JdbcResource>
     java:app/myConnectionPool <JdbcConnectionPool>
    Command list-applications executed successfully.
    

    This shows that the resources created for us during the application deployment. The resources are deployed in “java:app” prefix which is defined by the Java EE 6 namespace. These commands can also be invoked for different sub-components of an application, such as a WAR file within an EAR, by giving the command:
    asadmin list-applications --subcomponents --resources
    

    and then the module-specific resources are shown accordingly.
  10. The database connection pool can be pinged using the following command:
    ~/tools/glassfish/3.1/glassfish3 >./bin/asadmin ping-connection-pool --appname AppScopedResources java:app/myConnectionPool
    Command ping-connection-pool executed successfully.
    
  11. The property values of the resources (such as connection pool size) can be changed using
    ~/tools/glassfish/3.1/glassfish3 >./bin/asadmin get applications.application.AppScopedResources.resources.jdbc-connection-pool.java:app/myConnectionPool.max-pool-size
    applications.application.AppScopedResources.resources.jdbc-connection-pool.java:app/myConnectionPool.max-pool-size=32
    Command get executed successfully.
    

    And be changed using the “set” command. These properties can be preserved across multiple redeployments by specifying the following additional property:

    --properties preserveAppScopedResources=true

This is also explained in a screencast at GlassFishVideos.

You can try all these features in GlassFish 3.1. Download now!

About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today