To take advantage of this new functionality, developers must implement
some scripts on the web pages that host their applications.
The scripts determine whether the end-user's browser is Netscape
Navigator or Internet Explorer and whether they already have Java Web
Start installed on their system. Depending on these determinations,
additional script on the application's web page can take action to
initiate an automatic download and installation of Java Web Start
followed by download and installation of the application.
Developing applications that can be deployed with Java Web
Start are generally the same as developing a stand-alone application for
the Java 2 platform. Hence, the entry point for the application is the
standard public static void main(String[] argv).
However, in order to support Web deployment -- automatic download and
launching of the application -- and to ensure that an application can run
in a secure sandbox, there are a few added considerations:
Retrieving Resources from JAR files
Java Web Start only transfers JAR files from the Web server to the
client machine. It determines where to store the JAR files on the
local machine. Thus, an application cannot use disk-relative references
to resources such as images and configuration files.
All application resources must be retrieved from the JAR files specified
in the resources section of the JNLP file, or retrieved explicitly
using an HTTP request to the Web server. We recommend storing resources
in JAR files, since they will be cached on the local machine by Java Web
Start.
The following code example shows how to retrieve images from a JAR file:
// Get current classloader
ClassLoader cl = this.getClass().getClassLoader();
// Create icons
Icon saveIcon = new ImageIcon(cl.getResource("images/save.gif"));
Icon cutIcon = new ImageIcon(cl.getResource("images/cut.gif"));
...
The example assumes that the following entries exist in one of the JAR
files for the application:
images/save.gif
images/cut.gif
Security and Code Signing
Java Web Start addresses the security issues of:
-
Protecting users against malicious code (intentional & unintentional)
that may affect local files
-
Protecting enterprises against code that may attempt to access or destroy
data on networks
Applications launched with Java Web Start are -- by default -- run in a
restricted environment where they have limited access to local computing
resources, such as storage devices and the local network. In this sandbox
environment, Java Web Start can guarantee that a downloaded and potentially
untrusted application cannot compromise the security of the local files
or the network.
An additional security feature supported by Java Web Start is digital
code signing. If an application being invoked is delivered in one or more
signed JAR files, Java Web Start will verify that the contents of the JAR
file have not been modified since they were signed. If verification of
a digital signature fails, Java Web Start will not run the application,
since it may have been compromised by a third-party.
The support for code signing is important for both users and for application
service providers. This service makes it possible for users to verify that
an application comes from a trusted source. Because the application service
provider signs the code, both can be ensured that no other party can impersonate
the application on the Web. A signed application that is trusted by the
user can also request additional system privileges, such as access to a
local disk.
Java Web Start presents a dialog displaying the application's origin,
based on the signer's certificate, before the application is launched. Thereby
allowing the user to make an informed decision whether to grant additional
privileges to the downloaded code, or not.
An application can request full access to a client system when all its
JAR files are signed by including the following settings in the JNLP file:
<security>
<all-permissions/>
</security>
The implementation of code signing in Java Web Start is based on the
security API in the core Java 2 Platform. The Java 2 SE JRE 1.2.x supports
code signing with the SHAwithSDA algorithm. Java 2 SE JRE 1.3 also supports
MD2withRSA and MD5withRSA. The MD5withRSA is currently the most often used
algorithm.
Developers sign code for use with Java Web Start in the same
manner as for Java Applets by using the standard jarsigner tool from the
Java 2 SE SDK. The documentation for the jarsigner tool provides examples on
how to sign code, create test certificates, and other signing related issues.
Java Web Start also support use of the Netscape signtool when used with
the Java 2 SE JRE 1.3.0. See the Netscape Web site for details: http://developer.netscape.com/software/signedobj/
Signing JAR Files with a Test Certificate
Here are the steps needed to sign a JAR file with a test certificate:
-
Make sure that you have a JDK 1.2 or JDK 1.3 keytool and jarsigner in your path
(located in the J2SE SDK bin directory).
-
Create a new key in a new keystore as follows:
keytool -genkey -keystore myKeystore -alias myself
You will get prompted for a information about the new key, such as password,
name, etc. This will create the myKeystore file on disk.
-
Then, create a self-signed test certificate as follows:
keytool -selfcert -alias myself -keystore myKeystore
This will prompt for the password. Generating the certificate takes a few minutes.
-
Check to make sure that everything is ok. To list the contents of the keystore, use
the command:
keytool -list -keystore myKeystore
It should list something like:
Keystore type: jks
Keystore provider: SUN
Your keystore contains 1 entry:
myself, Tue Jan 23 19:29:32 PST 2001, keyEntry,
Certificate fingerprint (MD5):
C2:E9:BF:F9:D3:DF:4C:8F:3C:5F:22:9E:AF:0B:42:9D
-
Finally, sign the JAR file with the test certificate as follows:
jarsigner -keystore myKeystore test.jar myself
Repeat this step on all of your JAR files.
Please note that a self-signed test certificate should only be
used for internal testing, since it does not provide any guarantees
about the identity of the user and therefore cannot be trusted. A
trust-worthy certificate can be obtained from a certificate authority,
such as VeriSign, and should be used when the application is put into
production.
How to Encode JNLP Files in UTF-8
Beginning with Java Web Start version 1.2, JNLP files may be encoded in
any character encoding supported by the J2SE platform. (See the
J2SE
documentation for a list of supported encodings.)
Specify an encoding in the XML prolog of the JNLP file.
For example, the following line indicates that the JNLP file will be
encoded in UTF-16.
<?xml version="1.0" encoding="utf-16"?>
The XML prolog itself must be UTF-8 encoded.
The format used in this release correspond to the format
specified in the Java Network Launching Protocol and API (JNLP) Specification, v1.0.
This document describes the most commonly used elements of the JNLP
file. Refer to the specification for a complete description of the format.
The JNLP file is an XML document. The following shows a complete example
of a JNLP file:
<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for SwingSet2 Demo Application
-->
<jnlp
spec="1.0+"
codebase="http://javaweb.eng.com/jaws/apps"
href="swingset2.jnlp">
<information>
<title>SwingSet2 Demo Application</title>
<vendor>Sun Microsystems, Inc.</vendor>
<homepage href="docs/help.html"/>
<description>SwingSet2 Demo Application</description>
<description kind="short">A demo of
the capabilities of the Swing Graphical User Interface.</description>
<icon href="images/swingset2.jpg"/>
<icon kind="splash" href="images/splash.gif"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.3"/>
<jar href="lib/SwingSet2.jar"/>
</resources>
<application-desc main-class="SwingSet2"/>
</jnlp>
The example shows the basic outline of the document. The root element
is jnlp, which has four subelements: information, security,
resources,
and application-desc. In addition, Java Web Start also supports
launching Applets by using the applet-desc element. The elements
are described in more detail below.
The JNLP Element
spec attribute: This attribute must be 1.0 or higher to work with this
release. The default value is "1.0+". Thus, it can typically be omited.
codebase attribute: All relative URLs specified in href
attributes in the JNLP file is using this URL as a base.
href attribute: This is a URL pointing to the location of the
JNLP file itself. Java Web Start requires this attribute to be
set in order for the application to be included in the Application Manager.
The Information Element
title element: The name of the application.
vendor element: The name of the vendor of the application.
homepage element: Contains a single attribute, href,
which is a URL locating the home page for the Application. It is used by
the Application Manager to point the user to a Web page where they can
find more information about the application.
description element: A short statement about the application.
Description elements are optional. The kind attribute defines
how the description should be used, it can have one of the following values:
-
one-line: If a reference to the application is going to appear on
one row in a list or a table, this description will be used.
-
short: If a reference to the application is going to be displayed
in a situation where there is room for a paragraph, this description is
used.
-
tooltip: A description of the application intended to be used as
a tooltip.
Only one description element of each kind can be specified. A description
element without a kind is used as a default value. Thus, if Java Web Start
needs a description of kind short, and it is not specified in the JNLP
file, then the text from the description without an attribute is used
All descriptions contain plain text. No formatting, such as HTML tags
is supported.
icon element: Contains an HTTP URL to an image file in either
GIF or JPEG format. The icons are used to represents the application when
Java Web Start presents the application to the user during launch, in the
Application Manager, and in desktop shortcuts. A 64x64 icon is shown during download
and a 32x32 for desktop icons and in the application manager. Java Web Start
automatically resizes an icon to the appropriate size.
Optional width and height attributes can be used to
indicate the size of the images.
The optional kind="splash" attribute may be used in an
icon element to indicate that the image is to be used as a "splash" screen
during the launch of an application. If the JNLP file does not contain an
icon element with a kind="splash"
attribute, but does contain another icon tag, Java Web Start will
display a splash screen consisting of the image specified by the icon
element on the left and the application's title and vendor on the right.
If the JNLP file does not contain any icon images, the splash image
will consist of the application's title and vendor, as taken from the JNLP file.
Splash images will be surrounded by a border defined by Java Web Start.
The first time an application is launched following the addition or modification
of the icon element in the JNLP file, the old splash image will
still be displayed. The new splash image will appear on the second and
subsequent launches of the application.
offline-allowed element: The optional offline-allowed
element indicates if the application can be launched offline.
Applications that are not marked offline in the JNLP file will not be
able to be launched through the Application Manager, if the offline checkbox
is checked. The default is that an application only works if the client
system is online.
The offline-allowed element also controls how Java Web Start checks for an update
to an application. If the element is not specified, i.e., the application is required
to be online to run, Java Web Start will always do a check for an updated version before
the application is launched. And if an update is found, the new application will be
downloaded and launched. Thus, the user is guaranteed to always be running the latest
version of the application. However, the application will not be able to run offline.
If offline-allowed is specified, Java Web Start will also try to see if an update
is available. However, if the application is already downloaded, then this check will
timeout after a few seconds, and in that case the cached application will be launched
instead. Thus, in this situation, given a reasonable fast server connection, the user
will in most cases run the lastest version of the application, but it is not guaranteed.
However, offline launching is supported.
The Security Element
Each application is, by default, run in a restricted execution environment,
similar to the Applet sandbox. The security element can be used to
request unrestricted access.
If the all-permissions element is specified, the application
will have full access to the client machine and local network. If an application
requested full access, then all JAR files must be signed. The user
will be prompted to accept the certificate the first time the application
is launched.
The Resources Element
The resources element is used to specify all the resources, such
as Java class files, native libraries, and system properties, that are
part of the application. A resource definition can be restricted
to a specific operating system, architecture, or locale using the os,
arch,
and locale attributes.
The resources element has 6 different possible subelements: jar,
nativelib,
j2se,
property,
package,
and extension. The package and extension elements
are not discussed in this developer's guide. See specification for details.
A jar element specifies a JAR file that is part of the application's
classpath. For example:
<jar href="myjar.jar"/>
The jar file will be loaded into the JVM using a ClassLoader
object. The jar file will typically contain Java classes
that contain the code for the particular application, but can also contain
other resources, such as icons and configuration files, that are available
through the getResource mechanism.
A nativelib element specifies a JAR file that contains native
libraries. For example:
<nativelib href="lib/windows/corelib.jar"/>
The JNLP Client must ensure that each file entry in the root directory
of the JAR file (i.e., /) can be loaded into the running process using
the System.loadLibrary method. Each entry must contain a platform-dependent
shared library with the correct naming convention, e.g., *.dll on Windows,
or lib*.so on Solaris/Linux. The application is responsible for doing
the actual call to System.loadLibrary.
Native libraries would typically be included in a resources
element that is guarded against a particular operating system and architecture.
For example:
<resources os="SunOS" arch="sparc">
<nativelib href="lib/solaris/corelibs.jar"/>
</resource>
By default, jar and nativelib resources will be downloaded
eagerly, i.e., they are downloaded and available locally to the JVM running
the application before the application is launched. The jar
and nativelib elements also allow a resource to be specified as
lazy.
This means that the resource does not necessarily need to be downloaded
onto the client system before the application is launched.
The download attribute is used to control whether a resource
is downloaded eagerly or lazily. For example:
<jar href="sound.jar"
download="lazy"/>
<nativelib href="native-sound.jar"
download="eager"/>
The j2se element specifies what Java 2 SE Runtime Environment
(JRE) versions an application is supported on, as well as standard parameters
to the Java Virtual Machine. Several JREs can be specified, which
indicates a prioritized list of the supported JREs, with the most preferred
version first. For example:
<j2se version="1.3"
initial-heap-size="64m"/>
<j2se version="1.2"/>
The version attribute refers to, by default, a particular revision
of the Java 2 platform. Current defined revisions are "1.2" and "1.3".
The JNLP specification also allows specifying exact product versions, such
as the Java 2 JRE 1.2.2-001 by Sun Microsystems, Inc.
Java Web Start does not consider a non-FCS JRE to match a
request for a particular platform version. For
example, a request of the form <j2se version="1.4+"> does not
consider an installed "1.4.0-beta" JRE as a match for the request. A JRE from
Sun Microsystems, Inc. is by convention (starting from 1.3.0) a non-FCS if
there is a dash (-) in the product version string. An application wishing to
run under any beta J2RE must explicitly specify a product version, i.e., also
using the href attribute in the j2se element.
For example, a proper request for a beta JRE:
<j2se version="1.4-beta"
href="http://java.sun.com/products/autodl/j2se"/>
The property element defines a system property that will be
available through the System.getProperty and System.getProperties
methods.
It has two required attributes: name and value.
For example:
<property name="key" value="overwritten"/>
The Application-Desc Element
The application element indicates that the JNLP file is launching
an application (as opposed to an Applet). The application element has an
optional attribute, main-class, which can be used to specify the
name of the application's main class, i.e., the class that contains the
public
static void main(String argv[]) method where execution must begin.
The main-class attribute can be omitted, if the first JAR file specified
in the JNLP File contains a manifest file containing the main class.
Arguments can be specified to the application be including one or more
nested argument elements. For example:
<application-desc main-class="Main">
<argument>arg1</argument>
<argument>arg2</argument>
</application-desc>
The Applet-Desc Element
Java Web Start has support for launching Java Applets. This support provides
easy migration of existing code to Java Web Start.
An Applet is launched using the applet-desc element instead
of the
application-desc element. For example:
<applet-desc
documentBase="http://..."
name="TimePilot"
main-class="TimePilot.TimePilotApp"
width="527"
height="428">
<param name="key1" value="value1"/>
<param name="key2" value="value2"/>
</applet-desc>
The JAR files that make up the Applet are described using the resources
element as for applications. The documentBase must be provided
explicitly since a JNLP file is not embedded in an HTML page. The rest
of the attributes correspond to the respective HTML applet tag elements.
The main-class attribute is used instead of the code
attribute. The main-class attribute is assigned the name
of the Applet class (without the .class extension).
This attribute can be omitted if the Applet class can be found
from the Main-Class manifest entry in the main JAR file.
Note: Applets must be packaged in JAR files in order to work with Java
Web Start.
The JNLP API is designed to provide additional information
to the application that would otherwise not be available using the standard
Java 2 SE API. The following code examples show how the following
services can be used: BasicService, ClipboardService,
DownloadService,
FileOpenService,
FileSaveService,
PrintService,
and PersistenceService.
The public classes and interfaces in the JNLP API are included in the
jnlp.jar
file. This JAR file must be included in the classpath when compiling source
files that use the JNLP API. For example (on Windows):
javac -classpath .;jnlp.jar *.java
The jnlp.jar file is included in the JNLP Developers Pack.
Using a 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 successes, otherwise 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 a 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 a DownloadService Service
The javax.jnlp.DownloadService service
allows an application to control how its own 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://java.sun.com/products/javawebstart/lib/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 a 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 kind of 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 a file open dialog.
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);
// as user to select multiple files through this service
FileContents [] fcs = fos.openMultiFileDialog(null, null);
} catch (Exception e) {
e.printStackTrace();
}
}
|
Using a 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 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 a PrintService Service
The javax.jnlp.PrintService service provides
methods for accessing 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 will then show this request to the user, and if accepted queue the
request to the printer.
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 a 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 (somewhat) 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 which 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
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 a FileContents
can be used to read from and write to a file:
import javax.jnlp.*;
...
FileOpenService fos;
//Initialize fos (see Using a 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 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 a 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();
}
}
|