views:

251

answers:

3

Hi I am profiling a java applet startup time. I have noticed that a huge jar of size 5MB is fully read every time a resource from the jar is requested. E.g. images log configuration files, I18N files etc.... Sould it behave that way? Is it possible just to jump to the correct point ? Is it possible to read the file only once? If I will switch to cache_archiv_ex and add a preload directive will it help? Example of where the jar file is opened:

java.io.FileInputStream.open(String)
java.io.FileInputStream.<init>(File)
com.sun.deploy.cache.DeployCacheHandler$2.run()
java.security.AccessController.doPrivileged(PrivilegedExceptionAction)
com.sun.deploy.cache.DeployCacheHandler.get(URI, String, Map)
sun.net.www.protocol.http.HttpURLConnection.plainConnect()
sun.net.www.protocol.http.HttpURLConnection.connect()
sun.net.www.protocol.http.HttpURLConnection.getInputStream()
sun.plugin.PluginURLJarFileCallBack.downloadJAR(URLConnection, boolean)
sun.plugin.PluginURLJarFileCallBack.access$000(PluginURLJarFileCallBack, URLConnection, boolean)
sun.plugin.PluginURLJarFileCallBack$2.run()
java.security.AccessController.doPrivileged(PrivilegedExceptionAction)
sun.plugin.PluginURLJarFileCallBack.retrieve(URL)
sun.net.www.protocol.jar.URLJarFile.retrieve(URL, URLJarFile$URLJarFileCloseController)
sun.net.www.protocol.jar.URLJarFile.getJarFile(URL, URLJarFile$URLJarFileCloseController)
sun.net.www.protocol.jar.JarFileFactory.get(URL, boolean)
sun.net.www.protocol.jar.JarURLConnection.connect()
sun.plugin.net.protocol.jar.CachedJarURLConnection.connect()
sun.plugin.net.protocol.jar.CachedJarURLConnection.getInputStream()
java.net.URL.openStream()
java.lang.ClassLoader.getResourceAsStream(String)
sun.plugin2.applet.Applet2ClassLoader.getResourceAsStream(String)
..
.. (real application code stack...)
..
..
java.awt.event.InvocationEvent.dispatch()
java.awt.EventQueue.dispatchEvent(AWTEvent)
java.awt.EventDispatchThread.pumpOneEventForFilters(int)
java.awt.EventDispatchThread.pumpEventsForFilter(int, Conditional, EventFilter)
java.awt.EventDispatchThread.pumpEventsForHierarchy(int, Conditional, Component)
java.awt.EventDispatchThread.pumpEvents(int, Conditional)
java.awt.EventDispatchThread.pumpEvents(Conditional)
java.awt.EventDispatchThread.run()
+2  A: 

getResourceAsStream is calling CachedJarURLConnection. Are you sure it's not caching the jar and only downloading it once? If it is, I would make sure your web server isn't reporting a different or incorrect last update date on the jar each time.

Paul Tomblin
The references to `FileInputStream` is a strong indication that this (reading from cache rather than socket) is indeed happening. What's interesting to me is that a Java application normally memory-maps its jarfiles. Although I can understand why an applet container wouldn't do that, it's possible that there's a setting in the JRE that would enable it (but I haven't looked).
kdgregory
It is reading from file. I see it when I profile the process Yourkit 9.0 EAP has a nice feature called probes which shows the files read and the amount of data they read.
lifey
Can you explain the reasoning for not using memory mapped files in applets ?
lifey
For one thing, it represents a security risk: you could construct a JARfile that contains executable code, then find a way to invoke that code from within the browser. It also represents an imposition on the browser's virtual memory space.
kdgregory
+2  A: 

you can also try to create an index to the jar file with

jar -i "jar file"

And check if you still get that amount of data transfered all the time.

Zeograd
A: 

Do you need an applet? Unless you need to embed the Java application within a page, then I suggest using Webstart.

kdgregory