2
votes

I'm fairly self-taught java, but thought I'd had a good idea until I can't get it to work.

What's the best way to deploy my server/client program?

Lets say my server is up and faithfully waiting a connection.

I need to be able to get a client to run my app, but with user-specific parameters.

What's to stop me from generating a JNLP "on the fly" inside a servlet on my website (so I can get custom arguments) as such:

String jnlpCodebase = "http://" + request.getLocalAddr() + ":" + request.getLocalPort() + request.getContextPath();
out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
out.println("<jnlp spec=\"1.0+\" codebase=\"" + jnlpCodebase + "\">");
out.println("<information>");
out.println("   <title>etc</title>");
out.println("   <vendor>etc</vendor>");
out.println("</information>");
out.println("<security>");
out.println("   <all-permissions/>");
out.println("</security>");
out.println("<resources>");
out.println("   <j2se version=\"1.6+\"/>");
out.println("   <jar href=\"web/MyGame.jar\" main=\"true\"/>");
out.println("</resources>");
out.println("<application-desc main-class=\"runtime.SSCCEServer\">");
out.println("   <argument>" + name + "</argument>");
out.println("</application-desc>");
out.println("</jnlp>");

(Where name is a java variable from the servlet)

User clicks a button -> forwarded to the servlet that generates a JNLP and fires off JWS -> Application is downloaded -> User presented with my lovely client GUI.

Because this isn't happening.

I have deployed the project (containing this servlet and the jar dependencies under WEB-INF) as a WAR file which is then deployed to a Tomcat server.

WEB-INF has lib/, classes (which only has the built servlet described above .class file), and a web.xml (describing the servlet, a mapping to it's name and describing a JDBC connection).

Can anyone think of any reasons why this design would fail? I've tried without a codebase, but this creates some very non-intuitive errors, and at least at the moment, my JNLP file seems fine (verified with http://pscode.org/janela/), however running gives:

#### Java Web Start Error:
#### Unable to load resource: .../MyGame.jar

With a Wrapped Exception

java.util.zip.ZipException: ZIP file must have at least one entry
at java.util.zip.ZipOutputStream.finish(Unknown Source)
at java.util.zip.DeflaterOutputStream.close(Unknown Source)
at java.util.zip.ZipOutputStream.close(Unknown Source)
at com.sun.deploy.net.HttpDownloadHelper.download(Unknown Source)
at com.sun.deploy.cache.Cache.downloadResourceToTempFile(Unknown Source)
at com.sun.deploy.cache.Cache.downloadResourceToCache(Unknown Source)
at com.sun.deploy.net.DownloadEngine.actionDownload(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getResourceCacheEntry(Unknown Source)
at com.sun.deploy.net.DownloadEngine.getResource(Unknown Source)
at com.sun.javaws.LaunchDownload$DownloadTask.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)

Google doesn't have much help on the particular exception, but if there's no valid reason why this shouldn't work, I'll keep trying.

EDIT 1: Changed the layout of the jar file and removed some libraries (notably the mysql one that is also in the war file?), as there is no need to bundle these with the jar. This has stopped the above error. I think there may have been a issue there? I also added a href to the j2se tag in the JNLP...

<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="web/MyGame.jar" main="true"/>
</resources>

and that seems to be running locally now.

EDIT 2: Still can't get past a NoCLassDefFoundException (NCDFE) no matter where I put a necessary ext lib. Where should log4j-1.2.17.jar go? I had originally thought in the WAR file's WEB-INF/lib folder, along with the line Class-Path: . lib/log4j-1.2.17.jar in the META-INF/MANIFEST.MF file. But that still showed NCDFE so i've windmilled it into other folders, changed the manifest and even tried putting the ext lib into the JAR rather than the WAR, but no avail. Where should it go.. just so i'm clear. (And what should be in the manifests of both the JAR and WAR files and WEB-INF folders?) I've looked at so many NCDFE posts on t'internets I think it's all becoming confusing fast.

2
if you open mygame.jar with winzip, does it contain stuff?Aksel Willgert
Yes. It contains all my class files and images for the app, a lib file with the log4j external in, and a META-INF folder containing some jarsigning files and a MANIFEST.MF file... Manifest-Version: 1.0 Ant-Version: Apache Ant 1.8.2 Class-Path: . lib/log4j-1.2.17.jar Created-By: Me Main-Class: package.MyGameHemmels
but conceptualy i think you are understanding jws right, so keep debuging :)Aksel Willgert
Cheers for the heads up. I'll get on a <sscce.org> sooner or later.Hemmels
What is the value of jnlpCodebase?Andrew Thompson

2 Answers

1
votes

The ressource web/MyGame.jar should be located in a web subdirectory of your war file. So do you have the following layout in your war?

app.war
  META-INF/
    MANIFEST.MF
  WEB-INF/
    web.xml
    classes/
      *.class
    lib/
      *.lib
  web/
    MyGame.jar
0
votes

One of those "play around and fix it" unfortunately. I've put MyGame.jar in the same place as the .jsps (root dir of WAR), MANIFEST refers to the extension jars (Class-Path:) in the lib folder. I'm sure I had that before.