aboutsummaryrefslogtreecommitdiff
path: root/nailgun_launcher/TrapSecurityManager.java
diff options
context:
space:
mode:
authorChristopher Vogt <oss.nsp@cvogt.org>2016-10-07 00:24:14 -0400
committerChristopher Vogt <oss.nsp@cvogt.org>2016-10-07 20:05:57 -0400
commit8529a70358921af282920c216a81609292c8ba6a (patch)
tree04a23a27b41c55fc6c5ab42c79406d2f41e14b79 /nailgun_launcher/TrapSecurityManager.java
parent95728f6041a32e081a1f4129b8483ef622179b45 (diff)
downloadcbt-8529a70358921af282920c216a81609292c8ba6a.tar.gz
cbt-8529a70358921af282920c216a81609292c8ba6a.tar.bz2
cbt-8529a70358921af282920c216a81609292c8ba6a.zip
Fix exit code trapping across classloaders
A SecurityManager is once installed globally and stays the same across all classloaders. TrapSecurityManager was installed this way, but it looked up the `trapExitCode` in it's own classloader, while classes in other classloaders (when cbt was using another version of cbt) were writing it to their own classloader. This flag needs to be in a global place instead to fix this, so we'll put it straight into the TrapSecurityManager itself.
Diffstat (limited to 'nailgun_launcher/TrapSecurityManager.java')
-rw-r--r--nailgun_launcher/TrapSecurityManager.java52
1 files changed, 48 insertions, 4 deletions
diff --git a/nailgun_launcher/TrapSecurityManager.java b/nailgun_launcher/TrapSecurityManager.java
index fada878..1626787 100644
--- a/nailgun_launcher/TrapSecurityManager.java
+++ b/nailgun_launcher/TrapSecurityManager.java
@@ -9,6 +9,33 @@ would be Nailgun's if running on Nailgun. If we do not delegate to Nailgun, it s
could in some cases kill the server process
*/
public class TrapSecurityManager extends ProxySecurityManager{
+ public static ThreadLocal<Boolean> trapExitCode(){
+ // storing the flag in the installed security manager
+ // instead of e.g. a static member is necessary because
+ // we run multiple versions of CBT with multiple TrapSecurityManager classes
+ // but we need to affect the installed one
+ SecurityManager sm = System.getSecurityManager();
+ if(sm instanceof TrapSecurityManager){
+ return ((TrapSecurityManager) sm)._trapExitCode;
+ } else {
+ try{
+ @SuppressWarnings("unchecked")
+ ThreadLocal<Boolean> res =
+ (ThreadLocal<Boolean>) sm.getClass().getMethod("trapExitCode").invoke(null);
+ return res;
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private final ThreadLocal<Boolean> _trapExitCode =
+ new ThreadLocal<Boolean>() {
+ @Override protected Boolean initialValue() {
+ return false;
+ }
+ };
+
public TrapSecurityManager(){
super(NailgunLauncher.initialSecurityManager);
}
@@ -19,21 +46,38 @@ public class TrapSecurityManager extends ProxySecurityManager{
Calling .super leads to ClassNotFound exteption for a lambda.
Calling to the previous SecurityManager leads to a stack overflow
*/
- if(!NailgunLauncher.trapExitCode.get()){
+ if(!TrapSecurityManager.trapExitCode().get()){
super.checkPermission(permission);
}
}
public void checkPermission( Permission permission, Object context ){
/* Does this methods need to be overidden? */
- if(!NailgunLauncher.trapExitCode.get()){
+ if(!TrapSecurityManager.trapExitCode().get()){
super.checkPermission(permission, context);
}
}
+
+ private static final String prefix = "[TrappedExit] ";
+
@Override
public void checkExit( int status ){
- if(NailgunLauncher.trapExitCode.get()){
- throw new TrappedExitCode(status);
+ if(TrapSecurityManager.trapExitCode().get()){
+ // using a RuntimeException and a prefix here instead of a custom
+ // exception type because this is thrown by the installed TrapSecurityManager
+ // but other versions of cbt need to be able to catch it, that do not have access
+ // to that version of the TrapSecurityManager class
+ throw new RuntimeException(prefix+status);
}
super.checkExit(status);
}
+
+ public static boolean isTrappedExit( Throwable t ){
+ return t instanceof RuntimeException && t.getMessage().startsWith(prefix);
+ }
+
+ public static int exitCode( Throwable t ){
+ assert(isTrappedExit(t));
+ return Integer.parseInt( t.getMessage().substring(prefix.length()) );
+ }
+
}