views:

222

answers:

2

I'm trying to do a Google App Engine project on OS X (latest and greatest). I'm using classes from javax.crypto, and I'm seeing an AccessControlException thrown when I try to initialize an instance of the Mac class. Here's the stack trace:

WARNING: Nested in java.lang.ExceptionInInitializerError:
java.security.AccessControlException: access denied (java.lang.RuntimePermission loadLibrary.keychain)
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:264)
    at java.security.AccessController.checkPermission(AccessController.java:427)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
    at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:76)
    at java.lang.SecurityManager.checkLink(SecurityManager.java:818)
    at java.lang.Runtime.loadLibrary0(Runtime.java:816)
    at java.lang.System.loadLibrary(System.java:993)
    at com.apple.crypto.provider.HmacCore.<clinit>(HmacCore.java:26)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
    at java.lang.Class.newInstance0(Class.java:350)
    at java.lang.Class.newInstance(Class.java:303)
    at java.security.Provider$Service.newInstance(Provider.java:1130)
    at javax.crypto.Mac.a(DashoA12275)
    at javax.crypto.Mac.init(DashoA12275)

Any ideas on

1 - what went wrong and how fix it

2 - if it's not fixable (I know Apple has not been the best supporter of Java in recent years), what's an alternative approach?

+1  A: 

Found a workround on google groups:

"To work around the local Mac SDK problem, you can pass --jvm_flag=-D--enable_all_permissions=true to your dev_appserver. This will cause the error to go away, but will unfortunately also disable most of the security checking in your local environment. "

bpapa
+1  A: 

I have a more complete answer but without access to Apple's crypto provider source we'll never be fully sure what permissions are required on all their platforms. Here's what I was able to get working for snow leopard:

You'll need to grant whatever codebase needs the crypto the following permissions:

grand codebase "your/code/base" { permission java.lang.RuntimePermission "loadLibrary.keychain"; permission java.io.FilePermission "/System/Library/Java/Extensions/-", "read"; permission java.io.FilePermission "/Library/Java/Extensions/-", "read"; permission java.io.FilePermission "/System/Library/Frameworks/JavaVM.framework/-", "read"; };

It appears there is some sort of search for the libkeychain.jnilib file that visits the first two locations before finding it in the Frameworks directory on OSX 10.6.2 for Java 1.6. Other versions of java and other versions of the OS may have additional or different search paths so the only way to solve it for each platform is to try, see the security permission exception, grant a file permission, then try again till it works. Fun.

One important caveat, if you try to load the crypto library into one classloader that is not part of this codebase then try to load it again into another classloader that is part of the codebase then you'll get a "native library already loaded in another classloader" exception.

x86 a3ist