8 JNLP API Examples

The JNLP API provides additional information to the application that would otherwise not be available using the standard Java Platform Standard Edition API. For untrusted applications, the JNLP API provides methods for operations such as reading and writing files or accessing the clipboard or printers, which would otherwise be prevented by the security manager.

The public classes and interfaces in the JNLP API are included in the javaws.jar file, which is in the lib directory. This JAR file must be included in the class path when compiling source files that use the JNLP API. For example on Windows:

javac -classpath .;javaws.jar *.java

The following code examples show how the JNLP services can be used:

Using the BasicService Service

The javax.jnlp.BasicService service provides a set of methods for querying and interacting with the environment similar to what the AppletContext provides for a Java applet.

The showURL method uses the JNLP API to direct the default browser on the platform to show the given URL. The method returns true if the request succeeds; otherwise, it returns false.

import javax.jnlp.*;
   ...

   // Method to show a URL
   boolean showURL(URL url) {
       try {
           // Lookup the javax.jnlp.BasicService object
           BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
           // Invoke the showDocument method
           return bs.showDocument(url);
       } catch(UnavailableServiceException ue) {
           // Service is not supported
           return false;
       }
    }

Using the ClipboardService Service

The javax.jnlp.ClipboardService service provides methods for accessing the shared system-wide clipboard, even for applications that are running in the restricted execution environment.

Java Web Start will warn the user of the potential security risk of letting an untrusted application access potentially confidential information stored in the clipboard, or overwriting contents stored in the clipboard.

import javax.jnlp;
    ...

    private ClipboardService cs;

    try {
        cs = (ClipboardService)ServiceManager.lookup
                 ("javax.jnlp.ClipboardService");
    } catch (UnavailableServiceException e) {
        cs = null;
    }

    if (cs != null) {
        // set the system clipboard contents to a string selection
        StringSelection ss = new StringSelection("Java Web Start!");
        cs.setContents(ss);
        // get the contents of the system clipboard and print them
        Transferable tr = cs.getContents();
        if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {
           try {
                String s = (String)tr.getTransferData(DataFlavor.stringFlavor);
                System.out.println("Clipboard contents: " + s);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

Using the DownloadService Service

The javax.jnlp.DownloadService service allows an application to control how its resources are cached.

The service allows an application to determine which of its resources are cached, to force resources to be cached, and to remove resources from the cache.

import javax.jnlp.*; 
    ... 

    DownloadService ds; 

    try { 
        ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService"); 
    } catch (UnavailableServiceException e) { 
        ds = null; 
    } 

    if (ds != null) { 

        try { 
            // determine if a particular resource is cached
            URL url = 
                    new URL("http://www.example.com/draw.jar"); 
            boolean cached = ds.isResourceCached(url, "1.0"); 
            // remove the resource from the cache 
            if (cached) { 
                ds.removeResource(url, "1.0"); 
            } 
            // reload the resource into the cache 
            DownloadServiceListener dsl = ds.getDefaultProgressWindow(); 
            ds.loadResource(url, "1.0", dsl); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

Using the DownloadService2 Service

The javax.jnlp.DownloadService2 service, introduced in the Java SE 6 update 18 release, provides the following methods:

  • getCachedResources – Lists cached resources that match the given version, URL, and resource type.
  • getUpdateAvailableResources – Checks and lists resources for which updates are available. If an application uses the version download protocol, then specify a version in the DownloadService2.ResourceSpec. If not, then specify a null value for the version.

An instance of the DownloadService2.ResourceSpec class specifies details about the resource to be checked.

import javax.jnlp.*;
...
DownloadService2 service = (DownloadService2)
                        ServiceManager.lookup("javax.jnlp.DownloadService2");

// create a new instance of ResourceSpec. In this example: 
// - resource is downloaded from a directory on http://foo.bar.com:8080
// - version is 2. [0-9]+
// - resource type is JAR 
ResourceSpec spec = new ResourceSpec("http://foo.bar.com:8080/.*", 2.*, service.JAR)

// returns all cached resources that match the given ResourceSpec  
ResourceSpec results[] = service.getCachedResources(spec);

// returns all resources for which an update is available on the 
// server http://foo.bar.com:8080.
results = service.getUpdateAvailableResources(spec);

Implementing the DownloadServiceListener Service

The javax.jnlp.DownloadServiceListener service provides methods to specify a customized loading progress indicator that indicates the progress of an application's download.

Using the FileOpenService Service

The javax.jnlp.FileOpenService service provides methods for importing files from the local disk, even for applications that are running in the restricted execution environment.

This interface is designed to provide the same type of disk access to potentially untrusted web-deployed applications that a web developer has when using HTML. HTML forms support the inclusion of files by displaying an Open dialog box.

import javax.jnlp.*; 
    ... 

    FileOpenService fos; 

    try { 
        fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService"); 
    } catch (UnavailableServiceException e) { 
        fos = null; 
    } 

    if (fos != null) { 
        try { 
            // ask user to select a file through this service 
            FileContents fc = fos.openFileDialog(null, null); 
            // ask user to select multiple files through this service 
            FileContents[] fcs = fos.openMultiFileDialog(null, null); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

Using the FileSaveService Service

The javax.jnlp.FileSaveService service provides methods for exporting files to the local disk, even for applications that are running in the restricted execution environment.

This interface is designed to provide the same level of disk access to potentially untrusted web-deployed applications that a web browser provides for contents that it is displaying.  Most browsers provide a Save As dialog box as part of their user interface.

import javax.jnlp.*; 
    ... 

    FileSaveService fss; 
    FileOpenService fos; 

    try { 
        fos = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService"); 
        fss = (FileSaveService)ServiceManager.lookup 
                                   ("javax.jnlp.FileSaveService"); 
    } catch (UnavailableServiceException e) { 
        fss = null; 
        fos = null; 
    } 

    if (fss != null && fos != null) { 
        try { 
            // get a file with FileOpenService 
            FileContents fc = fos.openFileDialog(null, null); 
            // one way to save a file 
            FileContents newfc = fss.saveFileDialog(null, null, 
            fc.getInputStream(), "newFileName.txt"); 
            // another way to save a file 
            FileContents newfc2 = fss.saveAsFileDialog(null, null, fc); 

        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

Also see Using FileContents.

Using the IntegrationService Service

The javax.jnlp.IntegrationService service provides methods for programmatic management of shortcuts. By using this service, an application can perform the following operations:

  • Create a desktop shortcut

  • Create a menu shortcut

  • Query and delete shortcuts

  • Create, query, and delete associations of an application with a MIME type or file extensions.

import javax.jnlp.*;
...

IntegrationService is = null;
try {
    is = (IntegrationService) ServiceManager.lookup("javax.jnlp.IntegrationService");
} catch(UnavailableServiceException use){
    ...
}

// creates a desktop and system menu shortcut; returns true if the shortcuts 
// were created successfully
boolean result = is.requestShortcut(true, true, null);

//removes all shortcuts for application
result = is.removeShortcuts();

// checks to see if there are shortcuts for the application
result = is.hasMenuShortcut() && is.hasDesktopShortcut());

// associates the application with the specified mime-type and file extensions
String mime = "x-application/aaa";
String [] exts = {"aaa", "abc"};
result = is.requestAssociation(mime, exts);

// checks if the application is associated with the specified mime-type and file extensions
result = is.hasAssociation(mime, exts);

// removes association between the application and the specified mime-type and file extensions
is.removeAssociation(mime, exts);

Using the PrintService Service

The javax.jnlp.PrintService service provides methods for access to printing, even for applications that are running in the restricted execution environment.

Using this service, an application can submit a print job. Java Web Start then shows this request to the user and, if accepted, queues the request to the printer.

Starting in Java Web Start 5.0, you can directly use the Java Printing APIs, and Java Web Start pops up a security dialog box that asks the user to grant PrintPermission if the application is running in a sandbox. There is no need to use the JNLP Printing APIs anymore. You can have full access to the Java Printing APIs in any JNLP application.

import javax.jnlp.*; 
    ... 

    PrintService ps; 

    try { 
        ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService"); 
    } catch (UnavailableServiceException e) { 
        ps = null; 
    } 

    if (ps != null) { 
        try { 
             
            // get the default PageFormat
            PageFormat pf = ps.getDefaultPage(); 

            // ask the user to customize the PageFormat
            PageFormat newPf = ps.showPageFormatDialog(pf); 

            // print the document with the PageFormat above
            ps.print(new DocToPrint()); 
           
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

    // Code to construct the Printable Document
    class DocToPrint implements Printable {
        public int print(Graphics g, PageFormat pageformat, int PageIndex){
            // code to generate what you want to print   
        }
    }

Using the PersistenceService Service

The  javax.jnlp.PersistenceService service provides methods for storing data locally on the client system, even for applications that are running in the restricted execution environment.

The service is designed to be similar to that which the cookie mechanism provides to HTML-based applications. Cookies allow a small amount of data to be stored locally on the client system. That data can be securely managed by the browser and can only be retrieved by HTML pages that originate from the same URL as the page that stored the data.

import javax.jnlp.*; 
    ... 

    PersistenceService ps; 
    BasicService bs; 

    try { 
        ps = (PersistenceService)ServiceManager.lookup("javax.jnlp.PersistenceService"); 
        bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService"); 
    } catch (UnavailableServiceException e) { 
        ps = null; 
        bs = null; 
    } 

    if (ps != null && bs != null) { 

        try { 
            // find all the muffins for our URL
            URL codebase = bs.getCodeBase(); 
            String [] muffins = ps.getNames(url); 

            // get the attributes (tags) for each of these muffins. 
            // update the server's copy of the data if any muffins 
            // are dirty 
            int [] tags = new int[muffins.length]; 
            URL [] muffinURLs = new URL[muffins.length]; 
            for (int i = 0; i < muffins.length; i++) { 
                muffinURLs[i] = new URL(codebase.toString() + muffins[i]); 
                tags[i] = ps.getTag(muffinURLs[i]); 
                // update the server if anything is tagged DIRTY 
                if (tags[i] == PersistenceService.DIRTY) { 
                    doUpdateServer(muffinURLs[i]); 
                } 
            } 

            // read in the contents of a muffin and then delete it 
            FileContents fc = ps.get(muffinURLs[0]); 
            long maxsize = fc.getMaxLength(); 
            byte [] buf = new byte[fc.getLength()]; 
            InputStream is = fc.getInputStream(); 
            long pos = 0; 
            while((pos = is.read(buf, pos, buf.length - pos)) > 0) { 
                // just loop 
            } 
            is.close(); 

            ps.delete(muffinURLs[0]); 

            // re-create the muffin and repopulate its data 
            ps.create(muffinURLs[0], maxsize); 
            fc = ps.get(muffinURLs[0]); 
            // don't append 
            OutputStream os = fc.getOutputStream(false); 
            os.write(buf); 
            os.close(); 

        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

   void doUpdateServer(URL url) { 
        // update the server's copy of the persistent data 
        // represented by the given URL 
        ... 
        ps.setTag(url, PersistenceService.CACHED); 
   } 

Using FileContents

javax.jnlp.FileContents objects encapsulate the name and contents of a file. An object of this class is used by the FileOpenService, FileSaveService, and PersistenceService. Here is an example of how an instance of FileContents can be used to read from and write to a file:

import javax.jnlp.*; 
    ... 

    FileOpenService fos; 

    //Initialize fos (see Using the FileOpenService Service example) 
    ... 

    if (fos != null) { 

        try { 

            // get a FileContents object to work with from the 
            // FileOpenService 
            FileContents fc = fos.openFileDialog(null, null); 

            // get the InputStream from the file and read a few bytes 
            byte [] buf = new byte[fc.getLength()]; 
            InputStream is = fc.getInputStream(); 
            int pos = 0; 
            while ((pos = is.read(buf, pos, buf.length - pos)) > 0) { 
                // just loop 
            } 
            is.close(); 

            // get the OutputStream and write the file back out 
            if (fc.canWrite()) { 
               // don't append 
               OutputStream os = fc.getOutputStream(false); 
               os.write(buf); 
            } 

        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

Using a JNLPRandomAccessFile

Instances of javax.jnlp.JNLPRandomAccessFile support both reading and writing to a random access file.  A random access file behaves like a large array of bytes stored in the file system.  Here is an example of how an instance of a JNLPRandomAccessFile can be used to write to a random access file:

import javax.jnlp.*; 
    ... 

    FileOpenService fos; 

    //Initialize fos (see Using the FileOpenService Service example) 
    ... 

    if (fos != null) { 
        try { 
           // ask the user to choose a file to open 
           FileContents fc = fos.openFileDialog(null, null); 

           // attempt to increase the maximum file length 
           long grantedLength = fc.getLength(); 
           if (grantedLength + 1024 > fc.getMaxLength()) { 
               // attempt to increase the maximum file size defined by 
               // the client 
               grantedLength = fc.setMaxLength(grantedLength + 1024); 
           } 

           // if we were able to increase the maximum allowable file size, 
           // get a JNLPRandomAccessFile representation of the file, and 
           // write to it 
           if (fc.getMaxSize() > fc.getLength() && fc.canWrite()) { 
               JNLPRandomAccessFile raf = fc.getRandomAccessFile("rw"); 
               raf.seek(raf.length() - 1); 
               raf.writeUTF("Java Web Start!"); 
               raf.close(); 
           } 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 

Using the SingleInstanceService Service

The javax.jnlp.SingleInstanceService provides a set of methods for applications to register themselves as singletons, and to register listeners for handling arguments passed in from different instances of applications.

import javax.jnlp.*; 
    ... 

    SingleInstanceService sis; 

    ... 

    try { 
        sis = 
(SingleInstanceService)ServiceManager.lookup("javax.jnlp.SingleInstanceService");
    } catch (UnavailableServiceException e) { sis=null; }

    ...

    
    // Register the single instance listener at the start of your application
    
    SISListener sisL = new SISListener();
    sis.addSingleInstanceListener(sisL);

    ...
    
    
    // Remember to remove the listener before your application exits
    
    sis.removeSingleInstanceListener(sisL);
    System.exit(0);

    
    // Implement the SingleInstanceListener for your application
    
    class SISListener implements SingleInstanceListener {
        public void newActivation(String[] params) {
            
            // your code to handle the new arguments here
            
            ...
        }
    }

Using an ExtendedService Service

The javax.jnlp.ExtendedService provides additional support to the current JNLP API. It allows applications to open specific files in the client's file system.

import javax.jnlp.*; 
    ... 

    ExtendedService es; 

    ... 

    try { 
        es = 
(ExtendedService)ServiceManager.lookup("javax.jnlp.ExtendedService");
    } catch (UnavailableServiceException e) { es=null; }

    ...

    
    // Open a specific file in the local machine
    
    File a = new File("c:\somefile.txt");

    ...
    
    
    // Java Web Start will pop up a dialog asking the user to grant permission
    // to read/write the file c:\somefile.txt
    
    FileContents fc_a = es.openFile(a);

    
    // You can now use the FileContents object to read/write the file
    
    ...

    
    // Open a specific set of files in the local machine
    
    File[2] fArray = new File[2];
    
    fArray[0] = a;
    fArray[1] = new File("c:\anotherFile.txt");

    
    // Java Web Start will pop up a dialog asking the user to grant permission
    // to read/write files in fArray
    
    FileContents[] fc_Array = es.OpenFiles(fArray);

    
    // You can now read/write the set of files in fc_Array using the
    // FileContents objects
    
    }

For detailed information about using the javaws command, see javaws in the Java Platform, Standard Edition Tools Reference.