Regression: startawt failure

Project:JNode GUI
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:closed
Description

The startawt command fails with a huge obscure exception which appears to be thrown in reflection related code. I don't know exactly when did this break but it might be related to: http://www.jnode.org/node/3021.

#1

I've been looking at this, and a few rebuilds of classlib and jnode later I can report that it is indeed related to the 3021 issue. It seems the patch for 3021 didn't cause the startawt regression. Rather it looks like the patch failed fix the problem in this case. I haven't tried undoing the patch, but I don't think it would help.

Maybe we are trying to fix this the wrong way, and we should really be viewing this as a bug in the JNode security manager. Someone (Levente?) has added a comment to the BufferedInputStream init code hinting that is where the real problem is.

#2

It turns out that reverting the 3021 patch does fix the startawt regression. I don't understand why ... but it does. However, reverting the patch it would cause the original regression with BufferedInputStream to reappear. Since I think it is more important for commands etc using BufferedInputStream to work than startawt, I'm not going to do that.

Someone who is an expert on JNode security needs to take a look at this. I've taken a look at the security manager code but I'm stuck on the problem that I cannot figure out how it is supposed to work. Specifically, I cannot see any documentation on what the various pragmas are supposed to mean, what parts of the code base are supposed to be trusted "by design", and to what level, and what permissions should be granted to a non-trusted command run from the command line.

In addition to the expert fixing this, WE NEED SOME DOCUMENTATION ... so that the expertise can be shared.

For the record, the initial trigger for these regressions (this one and 3021) has to be switching to use the OpenJDK version of BufferedInputStream that does this funky stuff with AtomicReferenceFieldUpdater to null the 'buf' field. Maybe the simple solution is just to assign null ... but you would assume that there is some good reason for the funkiness.

Anyway. I cannot do anything about this regression. Levente or some other JNode security expert needs to take a look.

#3

I've included code that reproduces this problem.
This code fragment fails even on sun's java (1.6.0_13 on ubuntu 9.04).

As far as I know it has nothing to do with the security manager, other than the fact that it introduces an anonymous inner class into the call stack.
In classlib-src, the implementation of AtomicReferenceFieldUpdater (especially the ensureProtectedAccess method in the Impl class) does not check if the caller is an inner class of the class the field is situated within. This is evident in the error message too:
"Class AtomicFieldUpdaterTest$1 can not access a protected member of class AtomicFieldUpdaterTest using an instance of AtomicFieldUpdaterTest"
Note the $1.

As this fails on sun's classlib, then I guess the implementation of OpenJDK's AtomicReferenceFieldUpdater must be more lenient.

I don't have OpenJDK on this machine so I can't test it out on there...

import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

public class AtomicFieldUpdaterTest {

    protected volatile byte buf[];

    public static void main(String[] args) {
	new AtomicFieldUpdaterTest();
    }

    public AtomicFieldUpdaterTest() {
	// This succeeds
	AtomicReferenceFieldUpdater.newUpdater(AtomicFieldUpdaterTest.class,  byte[].class, "buf").
                compareAndSet(AtomicFieldUpdaterTest.this, new byte[] {}, null);

	// This fails
	new Runnable() {
	    @Override
            public void run() {
		AtomicReferenceFieldUpdater.newUpdater(AtomicFieldUpdaterTest.class,  byte[].class, "buf").
                        compareAndSet(AtomicFieldUpdaterTest.this, new byte[] {}, null);
	    }
	}.run();
    }
}

#4

I think that this *might* be fixed by using the following:

    static {
        bufUpdater = java.security.AccessController.doPrivileged(
                new PrivilegedAction<AtomicReferenceFieldUpdater<BufferedInputStream, byte[]>>() {
                    @Override
                    public AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> run() {
                        return createUpdater();
                    }
                });
    }

	private static final AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> createUpdater() {
        return AtomicReferenceFieldUpdater.newUpdater(
                BufferedInputStream.class,  byte[].class, "buf");
	}

within BufferedInputStream. I'm going to rebuild the classlib jar now and give it a go.

#5

With the code-changes above applied to BufferedInputStream, it no longer spews forth exceptions when using startawt. In fact, startawt now does absolutely nothing! I can see it changing video modes, then blackness. But that could be a problem with my setup...

#6

I tried your fix and it works for me ... provided that I give VMware enough memory. (512Mb is no longer enough.)

Maybe someone else (Levente?) could confirm the fix works, commit it to classlib and push the JARs.

#7

Thank you for the patch and for testing it.
startawt works for me again.
I applied and committed the patch.

#8

Status:active» fixed

Lets call this "fixed"

#10

Status:fixed» closed

Manually closed