public void main(final String[] args) throws Exception {
//TODO reorganize this so it makes more sense. maybe use an interceptor stack.
Thread thread = Thread.currentThread();
ClassLoader oldClassLoader = thread.getContextClassLoader();
TransactionContext oldTransactionContext = transactionContextManager.getContext();
TransactionContext currentTransactionContext = null;
Subject oldCurrentCaller = ContextManager.getCurrentCaller();
Subject clientSubject = defaultSubject;
LoginContext loginContext = null;
try {
thread.setContextClassLoader(classLoader);
if (callbackHandlerClass != null) {
//look for a constructor taking the args
CallbackHandler callbackHandler;
try {
Constructor cArgs = callbackHandlerClass.getConstructor(new Class[] {String[].class});
callbackHandler = (CallbackHandler) cArgs.newInstance(new Object[] {args});
} catch (NoSuchMethodException e) {
callbackHandler = (CallbackHandler) callbackHandlerClass.newInstance();
}
loginContext = new LoginContext(realmName, callbackHandler);
try {
loginContext.login();
} catch (LoginException e) {
loginContext = null;
throw e;
}
clientSubject = loginContext.getSubject();
}
ContextManager.setCurrentCaller(clientSubject);
jndiContext.startClient(appClientModuleName, kernel, classLoader);
currentTransactionContext = transactionContextManager.newUnspecifiedTransactionContext();
if (clientSubject == null) {
mainMethod.invoke(null, new Object[]{args});
} else {
Subject.doAs(clientSubject, new PrivilegedAction() {
public Object run() {
try {
mainMethod.invoke(null, new Object[]{args});
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
return null;
}
});
}
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof Exception) {
throw (Exception) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new Error(e);
} finally {
if (loginContext != null) {
loginContext.logout();
}
jndiContext.stopClient(appClientModuleName);
thread.setContextClassLoader(oldClassLoader);
transactionContextManager.setContext(oldTransactionContext);
if (currentTransactionContext != null) {
currentTransactionContext.commit();
}
ContextManager.setCurrentCaller(oldCurrentCaller);
}
}