Java
  Home arrow Java arrow Page 5 - Deployment Frameworks
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
JAVA

Deployment Frameworks
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 5
    2005-04-12

    Table of Contents:
  • Deployment Frameworks
  • Reading from a JAR File
  • Signing Applets
  • Deploying with Java Web Start
  • Isolating Optional Packages
  • Deploying Multiple Applets as One
  • Lifecycle
  • MultiApplet
  • CroftSoftCollection

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Deployment Frameworks - Isolating Optional Packages


    (Page 5 of 9 )

    Isolating Optional Packages

    Assuming a JNLP API implementation is available on the client platform, the showDocument() method of class BasicService automatically launches the default web browser on the client platform using platform-independent code. However, you will often want to write your game code in such a way that it can still run in an environment where the JNLP libraries are not installed. Ideally, your compiled game code should be able to run as a browser applet, an executable JAR, and as a JNLP Java Web Start application without modification. You can do this by including code that loads the JNLP class libraries, if available on the client machine, or gracefully continue on if not.

      private static JnlpServices createJnlpServices ( )
      /////////////////////////////////////////////////       
    {
      try
       {
        return ( JnlpServices )
          Class.forName 
          ( JnlpServices.IMPL_CLASS_NAME ).newInstance ( );
      }
    catch ( Exception ex )
      {
       return null;
      }
    catch ( NoClassDefFoundError er )
      {
    return null;
     }
    }

    The trick to this is to use dynamic class loading. You could also use reflection to accomplish this feat, but I find that as a general rule it is better to use custom interfaces and dynamic class loading. You start by first separating out the code that statically links to the optional package library javax.jnlp. You then attempt to dynamically load that code using Class.forName().newInstance(). If JNLP is not installed, the attempt generates a NoClassDefFoundError which you can then catch and handle gracefully. The preceding code from class JnlpLib in package com.croftsoft.core.jnlp does just that.

    packagecom.croftsoft.core.jnlp;

    import java.io.*;
    import java.net.*;

    public interface JnlpServices
    /////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////
    {

    public static final String IMPL_CLASS_NAME
    = "com.croftsoft.core.jnlp.JnlpServicesImpl";

    [...]

    public boolean showDocument ( URL url )
      throws UnsupportedOperationException;

    In this case, JnlpServices is an interface in package com.croftsoft.core.jnlp with no static links to package javax.jnlp. IMPL_CLASS_NAME is the name of a class, JnlpServicesImpl. This class provides a concrete implementation of the JnlpServices interface that does require static links to the optional package. A custom interface reference allows your code to handle optional package libraries without static linking and without using reflection.


    CAUTION In teaching a course on Java game programming, I noted that forgetting to explicitly name dynamically linked classes in the Ant build file was one of the most common causes of grief for my students. This can be difficult to debug as it will not generate a compile-time error and might not generate a runtime error. The calling code might silently ignore a runtime error and carry on under the assumption that JnlpServicesImpl could not load dynamically because the game is not running within a JNLP client container. The truth of the matter, however, might be that JnlpServiceImpl could not be loaded because it was not compiled and included in the JAR file.

      public static final JnlpServices JNLP_SERVICES
         = createJnlpServices ( );

      [...]

      public static boolean showDocument ( URL url )
         throws UnsupportedOperationException
    /////////////////////////////////////////////////////////
    {
    check ( );

    return JNLP_SERVICES.showDocument ( url );
    }

    [...]

    private static void check ( )
      throws UnsupportedOperationException
    ////////////////////////////////////////////////////////
    {
      if ( JNLP_SERVICES == null )
      {
       throw new UnsupportedOperationException ( );
      }
    }

    Static method showDocument() in class JnlpLib uses the implementation class if it can be dynamically loaded. If not, it throws an UnsupportedOperation-Exception that the calling game code can catch and handle gracefully.

      package com.croftsoft.core.jnlp;

      import java.io.*;
      import java.net.*;

      import javax.jnlp.*;

      [...]

      public final class JnlpServicesImpl
        implements JnlpServices
      ///////////////////////////////////////////////////////
      //////////////////////////////////////////////////////
      {

     [...]

      public boolean showDocument ( URL url )
        throws UnsupportedOperationException
      /////////////////////////////////////////////////////
      {
        try
        {

         BasicService basicService = ( BasicService )
           ServiceManager.lookup ( "javax.jnlp.BasicService" );
         return basicService.showDocument ( url );
      }
      catch ( UnavailableServiceException ex )
      {
       throw ( UnsupportedOperationException )
        new UnsupportedOperationException ( ).initCause ( ex );
      }
     }

    When using the showDocument() method in AppletContext, an instance of AppletContext is retrieved using the applet instance’s own getAppletContext() method. An instance of interface BasicService, however, is retrieved using the static method lookup() of class javax.jnlp.ServiceManager.

    public static Object lookup ( String name )
      throws UnavailableServiceException;

    If an implementation of BasicService is not available from the JNLP client, the ServiceManager throws an UnavailableServiceException. JnlpServicesImpl converts this exception from the optional package javax.jnlp to an Unsupported-OperationException from the core package java.lang if it is thrown. Note that the Throwable.initCause() method is used to attach the original exception to the new exception for examination by the calling code.

    Dynamic Linking Using Reflection

    As an alternative, you can also dynamically load the JNLP classes using reflection as shown in this code excerpt from class JnlpProxy in package com.croftsoft.core.jnlp.

      private static Object getBasicServiceObject ( )
      /////////////////////////////////////////////////////
    {
      try
     
    {
      
    Class serviceManagerClass
        
    = Class.forName ( "javax.jnlp.ServiceManager" );
      
    Method lookupMethod = serviceManagerClass.getMethod 
         "lookup", new Class [ ] { String.class } );
      
    return lookupMethod.invoke (
        
    null, new Object [ ] { "javax.jnlp.BasicService" } );
     
    }
     
    catch ( Exception ex )
     
    {
      
    return null;
      }
    }
    Class Method is from core package java.lang.reflect.
     public static boolean showDocument ( URL url )
     /////////////////////////////////////////////////////////  {
      if ( basicServiceObject == null )
           {
             return false;
           }
           try
           {
            Method method=basicServiceClass.getMethod (
              "showDocument", new Class [ ] { URL.class } );
           Boolean resultBoolean = ( Boolean ) method.invoke (
            basicServiceObject, new Object [ ] { url } );
           return resultBoolean.booleanValue ( );
           }
           catch ( Exception ex )
           {
           
    ex.printStackTrace ( );
            
    throw new RuntimeException ( ex.getMessage ( ) );
           }
        }

    By saving a singleton static reference to the BasicService instance retrieved, we can then use it within our own static showDocument() method. The example method returns false if the client platform does not support JNLP, allowing the calling code to respond with a substitute behavior.

    In my opinion, dynamic linking using custom interfaces instead of reflection makes for more comprehensible code. I have found that you almost never need reflection techniques if you keep this in mind.

    This article is excerpted from Advanced Java Game Programming by David Wallace Croft (Apress, 2004; ISBN 1590591232). Check it out at your favorite bookstore today. Buy this book now.

    More Java Articles
    More By Apress Publishing


     

    JAVA ARTICLES

    - Deploying Multiple Java Applets as One
    - Deploying Java Applets
    - Understanding Deployment Frameworks
    - Database Programming in Java Using JDBC
    - Extension Interfaces and SAX
    - Entities, Handlers and SAX
    - Advanced SAX
    - Conversions and Java Print Streams
    - Formatters and Java Print Streams
    - Java Print Streams
    - Wildcards, Arrays, and Generics in Java
    - Wildcards and Generic Methods in Java
    - Finishing the Project: Java Web Development ...
    - Generics and Limitations in Java
    - Getting Started with Java Web Development in...






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 3 hosted by Hostway
    Stay green...Green IT