Hi, I was wondering how it would be possible to create an update-aware application (please note that I am not talking about Java Webstart, it’s a Java application somebody downloaded and installed on this computer.)?
Actually, the application should just mirror the behavior of Java Webstart. The program checks the JNLP file on the server and updates itself if necessary. I found a related article: http://www.ftponline.com/javapro/2003_06/magazine/features/mnadelson/
(EDIT: Moderator: BlahBlahBlahh: I’ve just seen that webpage crash two different computers running firefox/mozilla, so inserting a warning here. I suspect they’re running some broken javascript as an advert)
Most gamers do like to “download” games, rather than use “webstart”. I deliver my game both as “webstart” and “downloadable version”. Webstart is auto-update enabled by default, however, I would also like to add that capability to the downloadable version. The downloadable version basically should do the same as Java Webstart - checks the .JNLP webstart file and updates itself.
Should not be rocket science? How about something like that to start with (This code is for Java Web Start), do you think that would work (it’s from the article above). One problem with the code is the “runtime.exec” command, which would only work for Windows! I would need something platform independent!:
The ResourceChecker object solves the problem of Java web start applications being informed of updates during execution. It checks if the resources required have been updated on the Web server and is constructed using the name of the application's JNLP file.
package JavaWebStart;
import javax.jnlp.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.
ParserConfigurationException;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.net.*;
import java.io.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
/**
* This class is used to check application-specific
* recources defined within a Java Web JNLP
* specification.
*/
public class ResourceChecker
{
private HashMap resourceMap = new HashMap();
// Map of resources and their attributes
private Collection resourceList;
// List of resource names
private String jnlpFile; // Name of the JNLP file
private URL rootURL; // The root URL path to the
// Java Web Start resources
private final String resourceTags[] =
{"jar","nativelib","extension"};
/**
* Constructor. Takes a JNLP file name and caches
* the resources and attributes contained within
*/
public ResourceChecker(
String _jnlpFile) throws
UnavailableServiceException,
MalformedURLException, IOException,
ParserConfigurationException, SAXException
{
jnlpFile = _jnlpFile;
// Get the root URL path of the Java Web Start
// resources
BasicService bs = (
BasicService)ServiceManager.lookup(
"javax.jnlp.BasicService");
rootURL = bs.getCodeBase();
// Initialize resourceMap
cacheResources();
}
/**
* Creates the cache of initial Java Web Start
* resource attributes
*/
private void cacheResources() throws
MalformedURLException, IOException,
ParserConfigurationException, SAXException
{
URL jnlpURL = new URL(
rootURL.toString() + jnlpFile);
URLConnection jnlpURLConnection =
jnlpURL.openConnection();
resourceMap.put("JNLP", new ResourceInfo(
jnlpURLConnection));
resourceList = getResourceList(
jnlpURLConnection);
Iterator resourceListI =
resourceList.iterator();
while(resourceListI.hasNext())
{
String resourceName = (
String)resourceListI.next();
URL resourceURL = new URL(
rootURL.toString() + resourceName);
URLConnection resourceConnection =
resourceURL.openConnection();
resourceMap.put(resourceName, new
ResourceInfo(resourceConnection));
resourceConnection = null;
resourceURL = null;
}
jnlpURL = null;
jnlpURLConnection = null;
}
/**
* Determines if Java Web Start resources have
* been updated on the Web Server @returns TRUE
* if the resources have been updated, FALSE
* otherwise
*/
public boolean haveResourcesChanged() throws
MalformedURLException, IOException
{
URL jnlpURL = new URL(
rootURL.toString() + jnlpFile);
URLConnection jnlpURLConnection =
jnlpURL.openConnection();
ResourceInfo resourceInfo = (
ResourceInfo)resourceMap.get("JNLP");
ResourceInfo currentResourceInfo = new
ResourceInfo(jnlpURLConnection);
if (!resourceInfo.equals(currentResourceInfo))
{
return true;
}
currentResourceInfo = null;
Iterator resourceListI =
resourceList.iterator();
while(resourceListI.hasNext())
{
String resourceName = (
String)resourceListI.next();
URL resourceURL = new URL(
rootURL.toString() + resourceName);
URLConnection resourceConnection =
resourceURL.openConnection();
resourceInfo = (
ResourceInfo)resourceMap.get(resourceName);
currentResourceInfo = new
ResourceInfo(resourceConnection);
if (!resourceInfo.equals(currentResourceInfo))
{
return true;
}
currentResourceInfo = null;
resourceConnection = null;
resourceURL = null;
}
jnlpURL = null;
jnlpURLConnection = null;
return false;
}
/**
* Executes javaws using the URL of the JNLP
* file. This causes Java Web Start to
* synchronize and reload the parent application.
* Once javaws is executed, the parent
* applicationÕs current execution is terminated.
*/
public void relaunch() throws
MalformedURLException, IOException
{
String args[] = new String[2];
URL jnlpURL = new URL(
rootURL.toString() + jnlpFile);
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(
"c:\\program files\\java web start\\javaws.exe "
+ jnlpURL.toString());
try { process.waitFor(); } catch(
Exception ex) { }
System.exit(0);
}
/**
* The JNLP file is downloaded from the Web Server
* and all resource names are extracted and
* returned within a Collection
*/
private Collection getResourceList(
URLConnection _urlConnection) throws
ParserConfigurationException, SAXException,
IOException
{
ArrayList resourceList = new ArrayList();
Document xmlDocument = null;
Element xmlObjectElement = null;
int length = _urlConnection.getContentLength();
byte buffer[] = new byte[length];
InputStream inStream =
_urlConnection.getInputStream();
inStream.read(buffer, 0, (int)length);
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder =
factory.newDocumentBuilder();
ByteArrayInputStream xmlStream = new
ByteArrayInputStream(buffer);
xmlDocument = builder.parse(xmlStream);
for (int resourceCount = 0; resourceCount <
resourceTags.length; resourceCount++)
{
NodeList nodeList =
xmlDocument.getElementsByTagName(
resourceTags[resourceCount]);
for (int count = 0; count < nodeList.getLength();
count++)
{
Node node = nodeList.item(count);
NamedNodeMap attributes =
node.getAttributes();
for (int attributeCount = 0; attributeCount <
attributes.getLength(); attributeCount++)
{
Node attributeNode = attributes.item(
attributeCount);
String name = attributeNode.getNodeName();
if (name.equals("href"))
{
resourceList.add(
attributeNode.getNodeValue());
}
}
}
}
return resourceList;
}
}