Assume I have below simple applet. I wonder if the http request to get the jar is made by the browser or by jvm. If it is made by jvm, are browser's cookies and sessions sent to server?
<APPLET
CODE="FieldTestF.class"
WIDTH="100%" HEIGHT="90"
ARCHIVE = "FieldTestF.jar"
>
This example uses an applet.
</APPLET>
The applet JAR is downloaded by the JVM. All applets are associated with an instance of a URLClassloader (or a subclass - the sun.applet.AppletClassLoader in Sun JVMs) that is responsible for loading of all classes and resources required by an applet.
Apparently, most of the infrastructure required for loading of class files and resources is available in the Java runtime, and re-using the same would allow the Java plug-in to not worry about accessing browser internals for the most part.
I'll reproduce the salient parts of the OpenJDK codebase here, that performs this activity. You'll find the interesting stuff in the runLoader() method of sun.applet.AppletPanel:
/**
* Load the applet into memory.
* Runs in a seperate (and interruptible) thread from the rest of the
* applet event processing so that it can be gracefully interrupted from
* things like HotJava.
*/
private void runLoader() {
if (status != APPLET_DISPOSE) {
showAppletStatus("notdisposed");
return;
}
dispatchAppletEvent(APPLET_LOADING, null);
// REMIND -- might be cool to visually indicate loading here --
// maybe do animation?
status = APPLET_LOAD;
// Create a class loader
loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
// Load the archives if present.
// REMIND - this probably should be done in a separate thread,
// or at least the additional archives (epll).
String code = getCode();
// setup applet AppContext
// this must be called before loadJarFiles
setupAppletAppContext();
try {
loadJarFiles(loader); // <-- this is what loads the JAR files
applet = createApplet(loader);
...
Also, getting the browser to fetch the resources would complicate matters for the Java security model. This is in part, due to the fact that applets use their own AccessControlContext that has been setup for them. This context has a default set of permissions that are added to it when the applet is being initialized; the set includes the SocketPermission to connect to the server hosting the codebase, or the FilePermission allowing read access to the filesystem containing the codebase. If resource loading were to be done by the browser, then depending on how the plug-in is implemented the checks might simply not be performed leading to a possible break-down of the security model.
You can confirm the resource loading behavior of the JVM by looking at the network traffic, as indicated in the other answer. I'll post the screenshot from Fiddler as confirmation. The process column indicates which OS process is responsible for sending out the request (in this case it happens to be the Java application launcher java.exe). Apologies for the apparent poor quality of the image - you'll need to resize the image or open it in a new window.
I suppose I could have looked it up, but it seemed much more fun to sniff the connection between the browser and the server to find an answer.
It turns out the request is done by the JVM. This is observable because:
The user agent is Mozilla/4.0 ([OS here]) Java/[Java version here] instead of whatever your browser sends;
The applet file request does not originate from the same port the browser requests come from;
The browser does not acknowledge the requests in the request logs & developer tools.
However, the browser seems to pass cookies along to the JVM when it issues the HTTP request, which means your session data should be available.
Related
We are having a performance issue when loading our Swing application under an applet container.
The Swing client communicates with JBoss server using RMI protocol.
When comparing our webstart application VS the new Applet container , its seems that the
Object marshaling taking much more time in the applet.
The ObjectInputStream -> writeExternal (using the JBoss Client RMI infra ) taking too much time to complete , 3-5x times then the webstart
In our ENV we have full deployment that sync all JARS between the server and the client (applet or webstart) so we don't need to load them remotely
The applet tag look like this:
archive="[contain list of 100 JARS -> about 200 MB]"
codebase="http://[remoteApacheServer]/USERTEST:85600"
List item
List of params ...
When checked that on the applet bootstrap the Applet loaded all the JARS from the server
But checking with sniffer we saw that every time we marshaled a new Class the applet class loader didn't used the Local version and send another request to remoteApacheServer looking for the specific class.
We found out the solution for it: using applet parameter :
param name="codebase_lookup" value="false
also we saw that loading the JARS locally - setting local nodejs HTTP that will serve the JRAS and set the codebase to use this temp server also boostup the peformance .
even just create nodejs server that just proxying the request backto the original remoteApacheServer helped .
but still the performance is still not good :-(
we saw in the sniffer that the client sending a reqest every time with the applet codebase and the full list of archive (all 100 JARS) and we saw the RMI has a feature
(Dynamic code downloading using Java™ RMI) that the Server can Marshell an Object even if its not exists in its local CLASSPATH.
see RMI setttings here
Do you know any why to disable it - i think its can help use solving the performance issue.
maybe using the java.rmi.server.useCodebaseOnly ?
I have some client-server interaction and GWT is updating the webpage and making it look dynamic. This is working on Chrome and Firefox, however, IE (8,9,10) is caching the Responses. I am able to tell that its caching because I used httpwatch to view the exchange.
http://i.imgur.com/qi6mP4n.png
As you can see these Responses are being cached, how can stop IE from aggressively caching like Chrome and Firefox?
The browser is allowed to cache a) any GET request with b) the same url unless c) the server specifies otherwise. With those three criteria, you have three options:
Stop using GET, and use a POST instead. This may not make sense for your use case or your server, but without any further context in your question, it is hard to be more specific
Change the url each time the resource is requested. This 'cache-busting' strategy is often used to let the same file be loaded and not need to worry if it changed on the server or not, but to always get a fresh copy
Specify headers from the server whether or not the file should be cached, and if so, for how long.
If you are dealing with the <module>.nocache.js and <hash>.cache.html files, these typically should get a header set on them, usually via a filter (as is mentioned in the how to clear cache in gwt? link in the comments). The *.cache.* files should be kept around, because their name will change automatically (see bullet #2 above), while the *.nocache.* should be reloaded every time, since their contents might have changed.
We define in our Java application a custom HTTP User-Agent containing the following:
Software version
User language
Platform information (operating system family + release name)
Java version
We want this user agent to be applied to all HTTP connections created by the application, including those we open manually, but also those automatically created by the JRE, for example when a JEditorPane resolves external images referenced inside HTML code.
For this, we set the "http.agent" system property to points 1/2/3 (letting the JRE add by itself the Java version) at the startup of our application:
System.setProperty("http.agent", Version.getAgentString());
This works great when we run the application from a jar, but not from Java Web Start.
As a workaround, we manually set our full User-Agent to the connections we create manually:
public static HttpURLConnection openHttpConnection(URL httpURL) throws IOException {
HttpURLConnection connection = (HttpURLConnection) httpURL.openConnection();
connection.setRequestProperty("User-Agent", Version.getFullAgentString());
return connection;
}
But this does not handle the case where the connection is created by the JRE (JEditorPane example).
How can we set the user agent in this case ?
We have tried to change the value of sun.net.www.protocol.http.HttpURLConnection.userAgent by using reflection with this example, but it doesn't work, we're facing an IllegalAccessException.
We cannot neither set the User-Agent in the JNLP file as it is not possible to determine client information (user language + platform).
You can only set system properties from the JNLP file, not the started application. See http://docs.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/syntax.html for instructions on how to do this.
Unfortunately it appears that the data you are interested in is not available at that time, so this will most likely not end up as you need.
You may be able to use some of the newer proxying capabilities to get hold of the connection depending on your application. http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html.
An extreme solution could be to carry your own http proxy inside your application and then tell your application to use that, the proxy code then as the only one knows how to get out, with your added header fields.
I recently stumbled across a problem when starting my application via JNLP. I now narrowed it down to a java.security.AccessControlException, which denies me to shut down my ExecuterService.
So, I did some reading and found out that I'll need the permission (modifyThread) to successfully shut down the service. I also found out that I should use the <security>-tag (in the JNLP-file) to request it, but I'm a little confused about how.
The documentation of the tag says:
[...] If the all-permissions element is specified, the application
will have full access to the client machine and local network. If an
application requests full access, then all JAR files must be
signed. The user will be prompted [...]
From reading this it seems to me, that I can choose to either get all or no permissions... which seems like a confusing Implementation. Because I only need the one to shutdown my service.
I also read this article, telling me that I should not request all permissions, because I would then open up the users computer for malicious code.
So, is there a way to specify that I only need the specific permission (modifyThread) and I therefor don't need to sign my jar? Or will I have to go with the "sign my jar and request everything"-approach?
..will I have to go with the "sign my jar and request everything"-approach?
Yes. JWS permissions come in 3 levels1, the only one where modifying threads is permitted, is all-permissions.
1) JWS security levels
Sand-boxed. Provides a very limited environment. Access to things like printers and the local file-system is only permitted using the JNLP API services, which provide more limited forms of File after prompting the user. Come with window banners. Can only communicate with own server.
j2ee-application-client-permissions - provide those JNLP API services unprompted (after the user accepts the digitally signed code) removes the window banners.
all-permissions - pretty much anything, including replacing the existing security manager (yes, even 'all permissions' code gets a security manager in JWS - it is just very lenient).
Also chase the links from the JNLP & JWS pages. I can personally recommend those summaries & links.
I have a non-signed java applet interacting with the same host. Every time I click on an element in my page, the applet (which is a third part applet I have no control on) should load data from a URL. I say should, because for some files, I get
java.security.AccessControlException : access denied (java.util.PropertyPermission http.agent read)
and some other files are correctly loaded. All files are correctly readable and downloadable from the web server, and they are very simple text files.
I also found that, in some cases, files that previously returned the error are now loaded and continue to load, so it seems a cache is involved somehow.
Does any of you have an idea of what's going on here ? The behavior seems to be absolutely random, and I have no way of performing debug on this thing. Note: I used this applet to perform many other "single shot" file access, and it never gave me any problem. The only apparent difference I have is that now I do it "on-demand" via a javascript event.
What could be the cause, in the java of the applet or anywhere else ?
This is a bug in the Java VM. http://bugs.sun.com/view_bug.do?bug_id=6593830 This problem seems only occur with an applet. Java Web Start seems not affected.
Some http and https URL handlers use the http.agent to set the User-Agent header.
The correct way to handle this would be to make a copy of this particular system property available whether the permission is granted or not (as with a number of others). However, what has been done is to add it on to the permissions give to applets and JNLP apps. This means that if any code is loaded through another mechanism (say a call from JavaScript over LiveConnect), it wont have the permissions and there might be a failure. If the item is already cached, then there wont be a need to write a HTTP header, and therefore the property need not be read.
The applet is broken. It is trying to access the value of a property that the sandbox security rules say that it cannot.
Report this to the supplier of the applet, and ask for a bug fix or workaround.