开发者

Why does my applet get a java.security.AccessControlException: access denied (java.net.SocketPermission ...), and how can I avoid it?

We are clueless about why my client is encountering a Java Security exception in Safari. Could anyone help?

The exception occurs reliably in Safari on Windows. This involves a Java applet. The exception also occurs with Firefox and IE8 on Windows Vista.

Here are the steps to reproduce:

  1. Open Safari on Windows

  2. Click here: http://www.cengraving.com/s/item?itemId=CH003

  3. Click "Customize" (at bottom of screen)

  4. After the "Instant Proof" page loads, click "Add to cart."

Full stack trace:

java.security.AccessControlException: access denied (java.net.SocketPermission www.cengraving.com resolve)
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkConnect(Unknown Source)
    at sun.plugin.security.ActivatorSecurityManager.checkConnect(Unknown Source)
    at java.net.InetAddress.getAllByName0(Unknown Source)
    at java.net.InetAddress.getAll开发者_Python百科ByName(Unknown Source)
    at java.net.InetAddress.getAllByName(Unknown Source)
    at java.net.InetAddress.getByName(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.http.HttpClient.New(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at com.designapplet.a.f.a(Unknown Source)
    at com.designapplet.ui.c.a(Unknown Source)
    at com.designapplet.ui.c.for(Unknown Source)
    at com.designapplet.ui.DesignApplet.buy(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSInvoke.invoke(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at sun.plugin.javascript.JSClassLoader.invoke(Unknown Source)
    at sun.plugin.liveconnect.PrivilegedCallMethodAction.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
java.net.MalformedURLException: no protocol: 
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
java.net.MalformedURLException: no protocol: 
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at java.net.URL.<init>(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
    at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)


You can override the default security policy file used by the SecurityManager.

1) Create a text file (eg. applet.policy)

2) Grant all permissions to the applet

  grant {
   permission java.security.AllPermission;
  };

3) Run the applet with

-J-Djava.security.policy=applet.policy


i had the same problem. And solved this by self signing the applet...

used the following steps and it worked

javac AppletClass.java
jar cvf AppletClass.jar AppletClass.class
keytool -genkey -validity 3650 -keystore pKeyStore -alias keyName
keytool -selfcert -keystore pKeyStore -alias keyName-validity 3650
jarsigner -keystore pKeyStore AppletClass.jar keyName

just answer the questions it will ask and it will do the work

NOTE : i was getting the error for local read/write file


I have the same problem! JavaScript calls a public method of an applet that is embedded in the same document. This should trigger that the applet loads some data from "home", so the connection should be opened to the same domain from where the applet was loaded - which should be allowed also for unsigned applets without further privileges.

I also recognized this security exception only with Safari (5.0.2 for Windows, JRE 1.6.0_22). The same applet in IE and FireFox is doing well.

I also believe that this is a bug in the Java Sandbox of Safari.


EDIT: Using doPrivileged did not help but I found this workaround: If you "decouple" the JavaScript call from the requested execution through a timer event, the execution will no longer be prohibited by the security restriction that Safari puts into the game here. In detail:

  • the method that is called from JavaScript only creates a javax.swing.Timer (to schedule one event so the repeat-property must be set false). You can set the delay quite short (e.g. 50 ms).
  • The method call that is intended to be called has to be put into the ActionEvent listener (actionPerformed) which is called by the timer.

One problem that might make things a bit more complicated is that in the actionPerformed context only static variables are accessible. If the JavaScript call contains variables, these must be put by the initially called method into a staic "buffer" variable from which the scheduled event can read the value afterwards.

In my tests only the javax.swing.Timer provided the required decoupling whereas java.util.Timer could not be used for that purpose.


Thanks for the responses. I didn't award the bounty because while the answers were all helpful, none quite solved the problem.

Ultimately, I solved the problem by passing the data from the applet to the web page, then executing an AJAX call to communicate with the server. Not the most elegant solution, certainly, but it has proved effective thus far.

Try it out, and lemme know if it works for you.

Thanks again!


Is this an applet? If it is, you need to sign your applet for it to access a socket, (which seems to be what you are doing...)

See here for more information:

http://java.sun.com/developer/onlineTraining/Programming/JDCBook/signed.html


On Linux it works.

The Add to cart button executes the function

  function saveLayout() {

    showSaveMsg();
    var status = document.app.buy();
    var loc = "http://www.cengraving.com/s/cart";

    if (status == 'GOOD') {
      window.location = getCartUrl();
    } else {
      showErrorMsg(status);
    }
  } 

Some remarks:

  • Is it normal that the local var loc is defined after the app call and not used anyway?

  • Also, a try catch may help (in Javascript, wrapping the app.buy() call).

  • Besides, I did a bit of research on the Net, and some people - having the same error but from a different usage - report a ClassPath problem. Do you have anything specific that could prevent the relevant JRE to be utilized?


It's manifesting as a security exception, but the problem is really a bad URL. If you follow the stack, you'll see there is a MalformedURLException.

This is most likely caused by passing a URI somewhere that was expecting a URL. Through the LiveConnect API from the looks of it. I'd guess it's not finding a host name where one is expected, and is trying to connect to a default, probably localhost. That's disallowed bye the SecurityManager hence the SecurityException.

In href's you can use URI (e.g., HREF="/somepath") because the browser resolves that against the URL for the page itself to produce the a full URL (e.g., http://example.com/somepath).

You can do that in Java by using the [appropriate URL constructor][1].

Update: Ah, I misread; I thought that was a single stack trace.

There used to be a bug where liveconnect could access a jar: url and obtain an arbitrary socket connection. The fix for that might be causing an issue with opening url connections from the liveconnect thread. What happens, if in the buy method, you start a thread to perform the connection?

[1]: http://download.oracle.com/javase/6/docs/api/java/net/URL.html#URL(java.net.URL, java.lang.String)


JRE sandbox tries to prevent javascript originated method calls to do harmful things but only thing it does is making programmers life harder.

Best workaround I've found to this is to build a producer & consumer design pattern event queue which implements very loose coupling between javascript originated calls and actual "dirty work".

What really sucks is that a code which runs fine in XP or Win7 may throw exception in Vista.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜