Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>IMHO the meaning of this is that a thread is (implicitly) created and gets the NativeRMISecurityManager as its default SecurityManager.</p> </blockquote> <p>This is true, though it is not the cause of your error; the problem has to do with the use of ThreadLocal. The key property of a ThreadLocal is that every calling thread has its own value. In this case "user" is being set by (and for) the thread that initializes the NativeRMISecurityManager and sets it as the System Security Manager (presumably the main thread).</p> <p>However, some other thread (by the look of it the RMI message handling thread) is calling checkRead() - but the "user" field was never set for this thread! Thus the value comes back as null.</p> <p>Unless there is some reason to have different threads have different values - and I cannot discern one from your example - I would recommend making the "user" field a) a String, not a ThreadLocal and b) non-static. That should solve your null value problem.</p> <p>However, presuming that it is a requirement / design constraint, the trouble with the current architecture is that only the thread that instantiates the NativeRMISecurityManager actually gets to have a user - every other thread gets null.</p> <p>In delving into this with a little more depth, I think I need a better understanding of your problem domain to offer any helpful suggestions as to a fix. Further, there is nothing quick or dirty about Java's Security Architecture. However I will do my best working under a few assumptions:</p> <ol> <li>Threads created by the system are assumed to be trusted</li> <li>Threads created by your code must specify a user</li> <li>Children threads should inherit the user of the creating thread</li> </ol> <p>Potential implementation:</p> <pre><code>public class NativeRMISecurityManager extends RMISecurityManager { private static final boolean UNIX; static { String OS = System.getProperty("os.name").toLowerCase(); UNIX = (OS.compareTo("windows") != 0); /* Assume that if not * windows, then "UNIX/POSIX" */ } protected static InheritableThreadLocal&lt;String&gt; user = new InheritableThreadLocal&lt;String&gt;(); public static setThreadUser(String username) { user.set(username); } public NativeRMISecurityManager(String initialUser) { super(); // Set the user for the thread that constructs the security manager // All threads created as a child of that thread will inherit the user // All threads not created as a child of that thread will have a 'null' user setThreadUser(initialUser); } public void checkRead(String file) { super.checkRead(file); /* * If we are on a **IX platform we want to check that * the _user_ has access rights. */ if (UNIX) { if (file == null) { throw new SecurityException("file = NULL !!!"); } String str_user = NativeRMISecurityManager.user.get(); if (str_user != null) { // Note: sanitize input to native method int ret = c_checkRead(file, str_user); if (ret != 0) { throw new SecurityException("Access error: " + file); } } // Assume a system thread and allow access } } public native int c_checkRead(String file, String user); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload