guice in sandboxed webstart

115 views
Skip to first unread message

Christian

unread,
Apr 11, 2009, 8:28:50 PM4/11/09
to google-guice-dev
So I googled my way to the bug "Guice explodes if it doesn't have
System.getProperty permissions":

http://code.google.com/p/google-guice/issues/detail?id=350

I thought I would start to circle in on the issue, so I looked at this
exception that crashes my swing thread:

Caused by: java.security.AccessControlException: access denied
(java.util.PropertyPermission cglib.debugLocation read)
at java.security.AccessControlContext.checkPermission
(AccessControlContext.java:323)
at java.security.AccessController.checkPermission
(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:
532)
at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:
1285)
at java.lang.System.getProperty(System.java:652)
at com.google.inject.cglib.core.DebuggingClassWriter.<clinit>
(DebuggingClassWriter.java:35)

Apparently webstart is not allowed to call System.getProperty() on
just anything, or specifically "cglib.debugLocation" as it attempts
there. Only javaws.* and jnlp.* are open to use from the sandbox.

Looking at DebuggingClassWriter I see a workaround that should be
sufficient, simply catch and ignore exceptions from getProperty:

--- src/proxy/net/sf/cglib/core/DebuggingClassWriter.java 26 May
2008 04:06:26 -0000 1.14
+++ src/proxy/net/sf/cglib/core/DebuggingClassWriter.java 12 Apr
2009 00:20:11 -0000
@@ -32,15 +32,15 @@
private String superName;

static {
- debugLocation = System.getProperty(DEBUG_LOCATION_PROPERTY);
- if (debugLocation != null) {
- System.err.println("CGLIB debugging enabled, writing to
'" + debugLocation + "'");
- try {
+ try {
+ debugLocation = System.getProperty
(DEBUG_LOCATION_PROPERTY);
+ if (debugLocation != null) {
+ System.err.println("CGLIB debugging enabled, writing
to '" + debugLocation + "'");
Class.forName
("org.objectweb.asm.util.TraceClassVisitor");
traceEnabled = true;
- } catch (Throwable ignore) {
- }
- }
+ }
+ } catch (Throwable ignore) {
+ }
}

public DebuggingClassWriter(int flags) {


The cglib projects seems to be all dead, their dev-list is just full
of spam. Have you guys managed to contribute to it or is it as dead as
it looks? Time to fork? Git is lovely :)


PS.

If the above works to dodge one fail, this lovely stacktrace remains
that I dont even know (yet) what one can do about:

INFO: An error occurred while injecting members of DEVELOPMENT. Error
message: java.security.AccessControlException: access denied
(java.lang.RuntimePermission accessDeclaredMembers)
java.security.AccessControlException: access denied
(java.lang.RuntimePermission accessDeclaredMembers)
at java.security.AccessControlContext.checkPermission
(AccessControlContext.java:323)
at java.security.AccessController.checkPermission
(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:
532)
at java.lang.SecurityManager.checkMemberAccess(SecurityManager.java:
1662)
at java.lang.Class.checkMemberAccess(Class.java:2157)
at java.lang.Class.getDeclaredFields(Class.java:1742)
at com.google.inject.InjectorImpl.addInjectors(InjectorImpl.java:350)
...

Christian

unread,
Apr 11, 2009, 11:05:28 PM4/11/09
to google-guice-dev
On Apr 12, 2:28 am, Christian <chs...@gmail.com> wrote:
> So I googled my way to the bug "Guice explodes if it doesn't have
> System.getProperty permissions":
>
>    http://code.google.com/p/google-guice/issues/detail?id=350
>
> I thought I would start to circle in on the issue, so I looked at this
> exception that crashes my swing thread:

I got a bit further in quenching various problems orginating from the
webstart sandbox. Starting with a little wrapper called SafeProperty,
to eat up SecurityExceptions (Inspired by comment in the bug). Patch
further down. (I am working on the google guice svn trunk)

After wrapping try catch for SecurityExceptions, this little 18-hole
golf track manages to get me into the sandbox bunker again:

Caused by: java.security.AccessControlException: access denied
(java.lang.RuntimePermission createClassLoader)
at java.security.AccessControlContext.checkPermission
(AccessControlContext.java:323)
at java.security.AccessController.checkPermission
(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:
532)
at java.lang.SecurityManager.checkCreateClassLoader
(SecurityManager.java:594)
at java.lang.ClassLoader.<init>(ClassLoader.java:201)
at com.google.inject.internal.BytecodeGen$BridgeClassLoader.<init>
(BytecodeGen.java:247)
at com.google.inject.internal.BytecodeGen$2$1.run(BytecodeGen.java:
100)
at com.google.inject.internal.BytecodeGen$2$1.run(BytecodeGen.java:
98)
at java.security.AccessController.doPrivileged(Native Method)
at com.google.inject.internal.BytecodeGen$2.apply(BytecodeGen.java:
98)
at com.google.inject.internal.BytecodeGen$2.apply(BytecodeGen.java:
95)
at com.google.inject.internal.MapMaker$StrategyImpl.compute
(MapMaker.java:528)


This time I am very stumped. I assume that the sandbox would allow to
create a new classloader as long as it uses an existing one as its
parent (?). Is that somehting I could go deeper into and fix? If not,
is this part of a feature I can disable and still have something
useful?

Oh well, it is 5AM and i have spent way too much "spare" time on this.

Below, SafeProperty replacing System.getProperty where it hurts, plus
catching security exceptoins on getDeclared{Fields,Methods} that threw
SecurityException:

SafeProperty apparently not included. Oh well. just to methods.

Index: src/com/google/inject/spi/InjectionPoint.java
===================================================================
--- src/com/google/inject/spi/InjectionPoint.java (revision 929)
+++ src/com/google/inject/spi/InjectionPoint.java (working copy)
@@ -390,7 +390,12 @@
private interface Factory<M extends Member & AnnotatedElement> {
Factory<Field> FIELDS = new Factory<Field>() {
public Field[] getMembers(Class<?> type) {
+ try {
return type.getDeclaredFields();
+ }
+ catch(SecurityException se) {
+ return new Field[] { };
+ }
}
public InjectionPoint create(TypeLiteral<?> typeLiteral, Field
member, Errors errors) {
return new InjectionPoint(typeLiteral, member);
@@ -399,7 +404,12 @@

Factory<Method> METHODS = new Factory<Method>() {
public Method[] getMembers(Class<?> type) {
+ try {
return type.getDeclaredMethods();
+ }
+ catch(SecurityException se) {
+ return new Method[] { };
+ }
}
public InjectionPoint create(TypeLiteral<?> typeLiteral, Method
member, Errors errors) {
checkForMisplacedBindingAnnotations(member, errors);
Index: src/com/google/inject/internal/Errors.java
===================================================================
--- src/com/google/inject/internal/Errors.java (revision 929)
+++ src/com/google/inject/internal/Errors.java (working copy)
@@ -29,6 +29,7 @@
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.Message;
import com.google.inject.spi.TypeListenerBinding;
+import com.google.inject.internal.SafeProperty;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
@@ -62,7 +63,7 @@

// TODO(kevinb): gee, ya think we might want to remove this?
private static final boolean allowNullsBadBadBad
- = "I'm a bad hack".equals(System.getProperty
("guice.allow.nulls.bad.bad.bad"));
+ = "I'm a bad hack".equals(SafeProperty.getProperty
("guice.allow.nulls.bad.bad.bad"));

private final List<Message> errors;
private final Errors parent;
Index: src/com/google/inject/internal/BytecodeGen.java
===================================================================
--- src/com/google/inject/internal/BytecodeGen.java (revision 929)
+++ src/com/google/inject/internal/BytecodeGen.java (working copy)
@@ -17,6 +17,7 @@
package com.google.inject.internal;

import static com.google.inject.internal.Preconditions.checkNotNull;
+import com.google.inject.internal.SafeProperty;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -83,7 +84,7 @@

/** Use "-Dguice.custom.loader=false" to disable custom
classloading. */
static final boolean HOOK_ENABLED
- = "true".equals(System.getProperty("guice.custom.loader",
"true"));
+ = "true".equals(SafeProperty.getProperty("guice.custom.loader",
"true"));

/**
* Weak cache of bridge class loaders that make the Guice
implementation






Reply all
Reply to author
Forward
0 new messages