appel
|
 |
«
Posted
2009-12-02 14:36:12 » |
|
Trying to understand the relation between the applet tag and the game jar in pack200 games. Here's a game that was submitted: 1 2 3 4
| <APPLET CODE="G.class" width="480" HEIGHT="480"> <PARAM NAME="cache_archive" VALUE="drts-4k.jar" /> <PARAM NAME="java_arguments" VALUE="-Djnlp.packEnabled=true" /> </APPLET> |
The file that was uploaded for this game is named "drts-4k.jar.pack.gz". How does the applet know how to retrieve that file? Does it automagically read the cache_archive value, append ".pack.gz", and look that up from the webserver, ungzip it, and unpack it, and vola it has its jar!? What happens if the param is: 1
| <PARAM NAME="cache_archive" VALUE="applet.php?gid=999" /> |
? All go into a mess?
|
|
|
|
Bonbon-Chan
|
 |
«
Reply #1 - Posted
2009-12-02 15:04:33 » |
|
From this link, as I understand it : - the client will allways ask for the "*.jar" - it is up to the server to give the "*.jar.pack.gz" if the client support it (Accept-Encoding in the HTTP request). Other wise, it have to send the ".jar" - the client know if it got "*.jar" or "*.jar.pack.gz" from the CE (Content-Encoding I think) So I think it is OK to use a php page to send back the "*.jar" or "*.jar.pack.gz"
|
|
|
|
Markus_Persson
|
 |
«
Reply #2 - Posted
2009-12-02 15:09:48 » |
|
I think you can make the applet tag point directly at a .pack.gz as well.
And isn't it just ".pack.gz", not ".jar.pack.gz"? I mean, there's no jar in there.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
kappa
|
 |
«
Reply #3 - Posted
2009-12-02 15:17:20 » |
|
java 1.6 can use pack200.gz files directly without server involvement using the code shown in appel's first post.
since plugin1 does not have the ability to use <PARAM NAME="java_arguments" VALUE="-Djnlp.packEnabled=true" /> the server will have to send a pack200 encoding to get it to run on plugin1 and java 1.5
|
|
|
|
Bonbon-Chan
|
 |
«
Reply #4 - Posted
2009-12-02 15:22:43 » |
|
And isn't it just ".pack.gz", not ".jar.pack.gz"? I mean, there's no jar in there.
I just copy what is in the link  I think you can make the applet tag point directly at a .pack.gz as well If the apple tag point directly on the .pack.gz, you have to be sure that all explorer that will be use can understant it... I have no idea whish ones are compatible with it. You should make a try and ask us to do the test.
|
|
|
|
kappa
|
 |
«
Reply #5 - Posted
2009-12-02 15:26:05 » |
|
well it would have made much more sense to be able to use it directly, but as we found out yesterday when testing it, it doesn't.
thx Sun.
|
|
|
|
kappa
|
 |
«
Reply #6 - Posted
2009-12-02 15:29:10 » |
|
I think you can make the applet tag point directly at a .pack.gz as well.
seems like only lwjgl applets allow that atm 
|
|
|
|
Markus_Persson
|
 |
«
Reply #7 - Posted
2009-12-02 15:32:11 » |
|
Damnit, sun. When I tried a local .html file that pointed at a "M.pack.gz", a pack200 gz file, it worked. When I uploaded both to my webserver, it no longer worked, despite the file being there. I can kind of understand why they'd want to enforce backwards compatibility on the server side so it'll still provide jars for older jvms.. but this is really, REALLY overly complicated. And it's not like code written for 1.5 will run on 1.4 jvms anyway if you use new classes or functions. * Markus_Persson strangles sun
|
|
|
|
pjt33
|
 |
«
Reply #8 - Posted
2009-12-02 16:19:57 » |
|
Damnit, sun. When I tried a local .html file that pointed at a "M.pack.gz", a pack200 gz file, it worked. When I uploaded both to my webserver, it no longer worked, despite the file being there.
Is your server providing an accurate Content-Type header? It may be that for local files the browser infers it but for http-provided files it assumes that the server knows what it's talking about.
|
|
|
|
Riven
|
 |
«
Reply #9 - Posted
2009-12-02 16:29:53 » |
|
The fact that the Java plugin cannot infer (override) some default Content-Type header is bad enough, especially as it got the full file extension in the URL.
|
Hi, appreciate more people! Σ ♥ = ¾ Learn how to award medals... and work your way up the social rankings!
|
|
|
Games published by our own members! Check 'em out!
|
|
pjt33
|
 |
«
Reply #10 - Posted
2009-12-02 16:47:26 » |
|
The fact that the Java plugin cannot infer (override) some default Content-Type header is bad enough, especially as it got the full file extension in the URL.
Sure, but I was interested more in suggesting workarounds than ranting.
|
|
|
|
appel
|
 |
«
Reply #11 - Posted
2009-12-02 17:26:30 » |
|
Alright, it's working. I was just missing the "Content-Encoding: pack200-gzip" header.
|
|
|
|
michael bliem
Senior Newbie 
|
 |
«
Reply #12 - Posted
2009-12-02 18:12:47 » |
|
'dont reach the square' doesnt work for me (Applet G notloaded)
machine: Apple Powerbook G4 OSX 10.4.11 (fully updated) Java 1.5.0_19 (fully updated)
|
|
|
|
appel
|
 |
«
Reply #13 - Posted
2009-12-02 18:42:56 » |
|
'dont reach the square' doesnt work for me (Applet G notloaded)
machine: Apple Powerbook G4 OSX 10.4.11 (fully updated) Java 1.5.0_19 (fully updated)
Strange, seems to work for me, WinXP: Java Plug-in 1.6.0_15 Using JRE version 1.5.0_14-b03 Java HotSpot(TM) Client VM
Or do I need Java Plug-in 1.5.x despite having JRE 1.5.x?
|
|
|
|
michael bliem
Senior Newbie 
|
 |
«
Reply #14 - Posted
2009-12-02 18:50:37 » |
|
is there a java-plugin for mac? testing my version of java for applets gives me java 1.5.0_19 there is no java 1.6 for my machine, but maybe a plugin?
java applets compiled 1.6 will not work on any apple powerpc nor will they work for most leopard systems only snow-leopard can handle 1.6 applets
compiling with javac option -source 1.5 would help, but dont know if pack200 will work with 1.5?
|
|
|
|
appel
|
 |
«
Reply #15 - Posted
2009-12-02 19:05:19 » |
|
Hm... I have JDK 1.5.14 installed, how can I run the Applets with the 1.5.x browser plug-in? It seems to be gone from Firefox's Plugins list. I need to download and reinstall the 1.5 jdk?
|
|
|
|
michael bliem
Senior Newbie 
|
 |
«
Reply #16 - Posted
2009-12-02 19:34:26 » |
|
Hm... I have JDK 1.5.14 installed, how can I run the Applets with the 1.5.x browser plug-in? It seems to be gone from Firefox's Plugins list. I need to download and reinstall the 1.5 jdk?
maybe with appletviewer of jdk1.5?
|
|
|
|
Markus_Persson
|
 |
«
Reply #17 - Posted
2009-12-02 19:53:37 » |
|
compiling with javac option -source 1.5 would help, but dont know if pack200 will work with 1.5?
-target 1.5, however, will help.
|
|
|
|
Alan_W
|
 |
«
Reply #18 - Posted
2009-12-02 23:07:01 » |
|
I've written a new obfustificate / pack / zip chain which is getting the same sort of file size that Riven presented earlier. However I can't get the browser (using file open on the html file) to get the pack.gz in preference to the .jar using the jre1.6 only parameter tag. (I am using 1.6). If I remove the jar and just leave the pack.gz I get a nice class not found stacktrace. Can this be tested without recourse to a webserver?
My web hosting has .htaccess and php but no servlets. I need to check whether they're using Apache, as I've seen some examples on how to get the right files served up using that. Alternatively I'll need to hack out some PHP. Anyone got a non-servlet solution working yet?
|
Time flies like a bird. Fruit flies like a banana.
|
|
|
pjt33
|
 |
«
Reply #19 - Posted
2009-12-02 23:41:53 » |
|
1 2 3 4
| <APPLET CODE="G.class" width="480" HEIGHT="480"> <PARAM NAME="cache_archive" VALUE="drts-4k.jar" /> <PARAM NAME="java_arguments" VALUE="-Djnlp.packEnabled=true" /> </APPLET> |
Does this work for anyone locally? I'm finding that if I have 1 2 3
| <applet width="640" height="480" code="a.class"> <param name="cache_archive" value="grav4k_1v3.jar" /> </applet> |
it loads from the jar fine, but if I have 1 2 3 4
| <applet width="640" height="480" code="a.class"> <param name="cache_archive" value="grav4k_1v3.jar" /> <param name="java_arguments" value="-Djnlp.packEnabled=true" /> </applet> |
I get error messages 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| java.lang.ClassNotFoundException: a.class at sun.plugin2.applet.Applet2ClassLoader.findClass(Applet2ClassLoader.java:152) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Plugin2ClassLoader.java:445) at sun.plugin2.applet.Plugin2Manager.createApplet(Plugin2Manager.java:2880) at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Plugin2Manager.java:1397) at java.lang.Thread.run(Thread.java:619) Caused by: java.io.FileNotFoundException: /tmp/pack200/a/class.class (No such file or directory) at java.io.FileInputStream.open(Native Method) at java.io.FileInputStream.<init>(FileInputStream.java:106) at java.io.FileInputStream.<init>(FileInputStream.java:66) at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:70) at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:161) at sun.plugin2.applet.Applet2ClassLoader.getBytes(Applet2ClassLoader.java:469) at sun.plugin2.applet.Applet2ClassLoader.access$000(Applet2ClassLoader.java:46) at sun.plugin2.applet.Applet2ClassLoader$1.run(Applet2ClassLoader.java:126) at java.security.AccessController.doPrivileged(Native Method) at sun.plugin2.applet.Applet2ClassLoader.findClass(Applet2ClassLoader.java:123) ... 6 more |
I am boggled at -Djnlp.packEnabled=true causing it to interpret the <applet>'s code attribute as a fully qualified name rather than the name of a class file. Replacing it with code="a" doesn't help: it looks for a file /tmp/pack200/a.class and ignores /tmp/pack200/grav4k_1v3.pack.gz (Java 1.6.0_15 64-bit on Linux; errors obtained equally via plugin in Firefox and via appletviewer).
|
|
|
|
Alan_W
|
 |
«
Reply #20 - Posted
2009-12-03 00:04:32 » |
|
That's pretty much what I'm getting. If I leave the jar in the same directory, then the browser goes and gets that Ok. On the positive note, my hosting provider is using Apache, so hopefully I can fix up a server solution using .htaccess. However I think that's a project for the weekend.
|
Time flies like a bird. Fruit flies like a banana.
|
|
|
moogie
|
 |
«
Reply #21 - Posted
2009-12-03 00:10:57 » |
|
I have not been successful to use pack200 locally...
I have thought, but not investigated, about directly using game.pack.gz as instead of the game.jar in the applet tag, but append appropriate html response (with pack 200 mime type) message to the front of game.pack.gz to try and trick the JVM in to thinking it recieved a pack 200 archive from a server.
|
Java4k RIP 2014
|
|
|
kappa
|
 |
«
Reply #22 - Posted
2009-12-03 00:27:22 » |
|
@pjt33
can you try <param name="cache_archive" value="grav4k_1v3" /> instead? (without the .jar bit)
|
|
|
|
appel
|
 |
«
Reply #23 - Posted
2009-12-03 00:36:42 » |
|
I have not been successful to use pack200 locally...
I have thought, but not investigated, about directly using game.pack.gz as instead of the game.jar in the applet tag, but append appropriate html response (with pack 200 mime type) message to the front of game.pack.gz to try and trick the JVM in to thinking it recieved a pack 200 archive from a server.
Perhaps it requires a server sending a "Content-Encoding: pack200-gzip" header. Grr.. .I've been trying to accomplish this same thing, run an pack200 applet using the appletviewer, locally, but no luck. Why oh why does Sun need to make technologies such a pain to use client-side?
|
|
|
|
pjt33
|
 |
«
Reply #24 - Posted
2009-12-03 07:53:29 » |
|
@pjt33
can you try <param name="cache_archive" value="grav4k_1v3" /> instead? (without the .jar bit)
Same error.
|
|
|
|
pjt33
|
 |
«
Reply #25 - Posted
2009-12-05 14:10:28 » |
|
I won't claim it's pretty, but I don't think there are enough security flaws in this for anyone to do anything nasty to your machine. Tested and it allowed me to play the .pack.gz of Gravitational Fourks; the logging output is good enough to check that it is getting the file you think it is. I haven't played around with caching pragmas, because I want to get on with actually developing a game for this year, but I suspect they would be helpful. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
| import java.io.*; import java.net.*; import java.util.*;
public class HTTPD implements Runnable { private static File rootDir;
private final Socket sock;
private String request;
private Object resource;
private int responseCode;
private Map<String, String> requestHeaders = new HashMap<String, String>();
private Map<String, String> responseHeaders = new HashMap<String, String>();
private HTTPD(Socket sock) { this.sock = sock; }
public static void main(String[] args) throws IOException { if (args.length < 1 || args.length > 2) usage(); rootDir = new File(args[0]); if (!rootDir.isDirectory()) usage(); int port = 8080; if (args.length == 2) { try { port = Integer.parseInt(args[1]); } catch (NumberFormatException nfe) { usage(); } }
ServerSocket serverSock = new ServerSocket(port); while (true) { Socket sock = serverSock.accept(); if (!sock.getInetAddress().isLoopbackAddress()) { System.out.println("Denying request from non-local IP "+sock.getInetAddress()); sock.close(); continue; }
new Thread(new HTTPD(sock)).start(); } }
private static void usage() { System.err.println("Usage: java HTTPD <root-dir> [port]"); System.err.println("Default port is 8080"); System.exit(-1); }
public void run() { try { final String utf8 = "UTF-8"; BufferedOutputStream outbin = new BufferedOutputStream(sock.getOutputStream()); PrintWriter out = new PrintWriter(new OutputStreamWriter(outbin, utf8)); BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream(), utf8));
InetAddress addr = sock.getInetAddress(); String line; while ((line = in.readLine()) != null) { if (request == null) { String[] bits = line.split(" "); if (bits.length == 3) { if ("GET".equals(bits[0])) { request = bits[1]; } else { responseCode = 501; resource = "Not supported"; } } else { responseCode = 400; resource = "Bad request"; break; } } else if (line.length() == 0) { break; } else { String[] bits = line.split(":"); if (bits.length == 2) { requestHeaders.put(bits[0].trim().toLowerCase(), bits[1].trim().toLowerCase()); } } }
if (responseCode == 0) { handleRequest(); }
int responseSize = 0; if (responseCode == 0 || resource == null) { responseCode = 501; resource = "Internal error"; } if (resource instanceof String) { resource = resource.toString().getBytes(utf8); responseHeaders.put("Content-Encoding", utf8); responseHeaders.put("Content-Type", "text/plain; charset=UTF-8"); } if (resource instanceof byte[]) responseSize = ((byte[])resource).length; else if (resource instanceof File) responseSize = (int)((File)resource).length(); responseHeaders.put("Content-Length", Integer.toString(responseSize));
out.println("HTTP/1.1 "+responseCode); for (Map.Entry<String, String> e : responseHeaders.entrySet()) { out.println(e.getKey()+": "+e.getValue()); } out.println(); out.flush(); if (resource instanceof byte[]) { outbin.write((byte[])resource); } else if (resource instanceof File) { FileInputStream fis = new FileInputStream((File)resource); byte[] buf = new byte[4096]; int len; while ((len = fis.read(buf)) != -1) { outbin.write(buf, 0, len); } fis.close(); }
System.out.println("["+addr+"] "+responseCode+" ("+responseSize+" bytes) for "+request);
outbin.close(); in.close(); } catch (IOException ioe) { ioe.printStackTrace(); } }
private void handleRequest() { try { request = URLDecoder.decode(request, "UTF-8"); } catch (UnsupportedEncodingException ufe) { InternalError err = new InternalError(); err.initCause(ufe); throw err; }
if (request.indexOf("..") >= 0) { responseCode = 401; resource = "Unauthorized"; return; }
if (!request.startsWith("/")) { request = "/" + request; } File file = new File(rootDir, request); if (!file.isFile()) { responseCode = 404; resource = "Not found"; } else { responseCode = 200; resource = file; String contentType = getContentType(request); if (contentType != null) { responseHeaders.put("Content-Type", contentType); } else { responseHeaders.put("Content-Type", "application/x-unknown"); } }
if (request.endsWith(".jar") && requestHeaders.get("accept-encoding") != null && requestHeaders.get("accept-encoding").contains("pack200-gzip")) { File _jar_pack_gz = new File(rootDir, request+".pack.gz"); File _pack_gz = new File(rootDir, request.replace("jar$", "pack.gz")); if (_jar_pack_gz.isFile() || _pack_gz.isFile()) { responseCode = 200; resource = _jar_pack_gz.isFile() ? _jar_pack_gz : _pack_gz; responseHeaders.put("Content-Type", "application/x-java-archive"); responseHeaders.put("Content-Encoding", "pack200-gzip"); } } }
private String getContentType(String request) { if (request.endsWith(".html")) return "text/html"; if (request.endsWith(".jar")) return "application/x-java-archive"; return null; } } |
|
|
|
|
Alan_W
|
 |
«
Reply #26 - Posted
2009-12-06 17:13:13 » |
|
I got pack200 working under Tomcat6 1. Install Tomcat 2. If using Vista and Tomcat installed under Program Files, change permissions to allow modify & write 3. Edit startup.bat in /bin to include "set JRE_HOME=C:\Program Files\Java\jre6" or whereever you have a JRE installed 4. Check tomcat works when you run startup.bat, and stops with shutdown.bat 5. Add directory 'java' under directory 'webapps'. 6. Create subdirectory 'WEB-INF' and copy in 'web.xml' from 'webapps/ROOT/WEB-INF' 7. Edit web.xml to include: <!-- The JNLP servlet, installed to support Pack200 for use in Java4K --> <servlet> <servlet-name>JnlpDownloadServlet</servlet-name> <servlet-class>jnlp.sample.servlet.JnlpDownloadServlet</servlet-class> </servlet>
<!-- The mapping for the JNLP servlet for Java4k -->
<servlet-mapping> <servlet-name>JnlpDownloadServlet</servlet-name> <url-pattern>*.jar</url-pattern> </servlet-mapping>
8. Create directory 'lib' under 'WEB-INF' 9. Copy in 'jnlp-servlet.jar', which you will find in the sample/jnlp/servlet direvtory in the java sdk 10. Add your .html and pack.gz files in the java directory. Note you also need the jar as the server looks for it - but it can be an empty file 11. Point your browser at http://localhost:8080/java/yourhtmlfile.html
|
Time flies like a bird. Fruit flies like a banana.
|
|
|
Ranger
|
 |
«
Reply #27 - Posted
2010-01-30 08:05:39 » |
|
Sorry, just confirming, it is not possible to test a pack200 file locally? We have to do it via the tomcat method? Are people actually doing that, or just hoping it works ok as a pack200 file and uploading to the Java4K site blindly?
|
|
|
|
pjt33
|
 |
«
Reply #28 - Posted
2010-01-30 09:05:42 » |
|
Sorry, just confirming, it is not possible to test a pack200 file locally? We have to do it via the tomcat method? Are people actually doing that, or just hoping it works ok as a pack200 file and uploading to the Java4K site blindly?
Look two posts before yours and you'll find a small self-contained web server which supports pack200. (I had posted it before, but I didn't look in this thread. Oh well, never mind).
|
|
|
|
Ranger
|
 |
«
Reply #29 - Posted
2010-01-30 21:14:46 » |
|
Look two posts before yours and you'll find a small self-contained web server which supports pack200.
(I had posted it before, but I didn't look in this thread. Oh well, never mind).
Hi pjt33. I can't seem to get it working. I start it up: java HTTPD myDir I have my html file with: 1 2 3
| <applet CODE="A.class" ARCHIVE="MyApplet.pack.gz" WIDTH="1000" HEIGHT="500"> <param name="java_arguments" value="-Djnlp.packEnabled=true" /> </applet> |
The web server reads the html file ok, but Java gives this error: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| load: class A.class not found. java.lang.ClassNotFoundException: A.class at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source) at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source) at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.io.IOException: open HTTP connection failed:http: at sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source) at sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source) at sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) ... 7 more Exception: java.lang.ClassNotFoundException: A.class |
I'm running java 1.6.0_13. The web server outputs this: 1 2 3
| [/0:0:0:0:0:0:0:1] 200 (833 bytes) for /indexPack200.html [/127.0.0.1] 404 (9 bytes) for /A.class [/127.0.0.1] 404 (9 bytes) for /A/class.class |
Any idea what I am doing wrong? Thanks! EDIT: Changed ARCHIVE="MyApplet.pack.gz" to ARCHIVE="MyApplet" and woohoo! It's working! Thanks for the server code pjt33! 
|
|
|
|
|