464
// in src/main/java/org/jboss/invocation/MarshallingInvokerInterceptor.java
public Object invoke(Invocation invocation)
throws Exception
{
/*
if(isLocal(invocation))
return invokeLocalMarshalled(invocation);
else
return invokeInvoker(invocation);
invokeLocalMarshalled is an optimized method for call-by-values. we don't need to serialize the entire Invocation
for having call-by-value.
*/
if(isLocal(invocation))
return invokeLocalMarshalled(invocation);
else
return invokeInvoker(invocation);
}
// in src/main/java/org/jboss/invocation/Invocation.java
public Object performCall(Object instance, Method m, Object[] arguments)
throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Exception
{
return m.invoke(instance,arguments);
}
// in src/main/java/org/jboss/invocation/ByValueInvokerInterceptor.java
public Object invoke(Invocation invocation)
throws Exception
{
// local interface
if (isLocal(invocation))
// The payload as is is good
return localInvoker.invoke(invocation);
else
// through the invoker
return invocation.getInvocationContext().getInvoker().invoke(invocation);
}
// in src/main/java/org/jboss/invocation/http/interfaces/Util.java
public static Object invoke(URL externalURL, Invocation mi)
throws Exception
{
if( log.isTraceEnabled() )
log.trace("invoke, externalURL="+externalURL);
/* Post the MarshalledInvocation data. This is using the URL class
for now but this should be improved to a cluster aware layer with
full usage of HTTP 1.1 features, pooling, etc.
*/
HttpURLConnection conn = (HttpURLConnection) externalURL.openConnection();
configureHttpsHostVerifier(conn);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("ContentType", REQUEST_CONTENT_TYPE);
conn.setRequestMethod("POST");
// @todo this should be configurable
conn.setRequestProperty("Accept-Encoding", "x-gzip,x-deflate,gzip,deflate");
OutputStream os = conn.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
try
{
oos.writeObject(mi);
oos.flush();
}
catch (ObjectStreamException e)
{
// This generally represents a programming/deployment error,
// not a communication problem
throw new InvocationException(e);
}
// Get the response MarshalledValue object
InputStream is = conn.getInputStream();
// Check the headers for gzip Content-Encoding
String encoding = conn.getHeaderField("Content-Encoding");
if( encoding != null && encoding.indexOf("gzip") >= 0 )
is = new GZIPInputStream(is);
ObjectInputStream ois = new ObjectInputStream(is);
MarshalledValue mv = (MarshalledValue) ois.readObject();
// A hack for jsse connection pooling (see patch ).
ois.read();
ois.close();
oos.close();
// If the encoded value is an exception throw it
Object value = mv.get();
if( value instanceof Exception )
{
throw (Exception) value;
}
return value;
}
// in src/main/java/org/jboss/invocation/http/interfaces/HttpInvokerProxy.java
public String getServerHostName() throws Exception
{
if( externalURL == null )
externalURL = Util.resolveURL(externalURLValue);
return externalURL.getHost();
}
// in src/main/java/org/jboss/invocation/http/interfaces/HttpInvokerProxy.java
public Object invoke(Invocation invocation)
throws Exception
{
// We are going to go through a Remote invocation, switch to a Marshalled Invocation
MarshalledInvocation mi = new MarshalledInvocation(invocation);
if( externalURL == null )
externalURL = Util.resolveURL(externalURLValue);
try
{
Object value = Util.invoke(externalURL, mi);
return value;
}
catch (InvocationException e)
{
// Unwrap the invoker servlet InvocationExceptions
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else if (t instanceof Error)
throw (Error) t;
throw new InvocationTargetException(t);
}
catch (IOException e)
{
throw new ServerException("IOE", e);
}
}
// in src/main/java/org/jboss/invocation/http/server/HttpInvoker.java
protected void startService()
throws Exception
{
checkInvokerURL();
Invoker delegateInvoker = new HttpInvokerProxy(invokerURL);
// Export the Invoker interface
ObjectName name = super.getServiceName();
Registry.bind(name, delegateInvoker);
log.debug("Bound Http invoker for JMX node");
}
// in src/main/java/org/jboss/invocation/http/server/HttpInvoker.java
public Object invoke(Invocation invocation)
throws Exception
{
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try
{
// Deserialize the transaction if it is there
MarshalledInvocation mi = (MarshalledInvocation) invocation;
Object tpc = mi.getTransactionPropagationContext();
Transaction tx = importTPC(tpc);
invocation.setTransaction(tx);
Integer nameHash = (Integer) invocation.getObjectName();
ObjectName mbean = (ObjectName) Registry.lookup(nameHash);
// The cl on the thread should be set in another interceptor
Object[] args = {invocation};
String[] sig = {"org.jboss.invocation.Invocation"};
Object obj = super.getServer().invoke(mbean,
"invoke", args, sig);
// Return the raw object and let the http layer marshall it
return obj;
}
catch (Exception e)
{
if (e instanceof MBeanException)
e = ((MBeanException)e).getTargetException();
if (e instanceof RuntimeMBeanException)
e = ((RuntimeMBeanException)e).getTargetException();
if (e instanceof RuntimeOperationsException)
e = ((RuntimeOperationsException)e).getTargetException();
// Only log errors if trace is enabled
if( log.isTraceEnabled() )
log.trace("operation failed", e);
throw e;
}
finally
{
Thread.currentThread().setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/invocation/http/server/HttpProxyFactory.java
public void setClientInterceptors(Element config) throws Exception
{
this.interceptorConfig = config;
Iterator interceptorElements = MetaData.getChildrenByTagName(interceptorConfig, "interceptor");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if( interceptorClasses != null )
interceptorClasses.clear();
else
interceptorClasses = new ArrayList();
while( interceptorElements != null && interceptorElements.hasNext() )
{
Element ielement = (Element) interceptorElements.next();
String className = null;
className = MetaData.getElementContent(ielement);
Class clazz = loader.loadClass(className);
interceptorClasses.add(clazz);
}
}
// in src/main/java/org/jboss/invocation/http/server/HttpProxyFactory.java
protected void startService() throws Exception
{
/** Create an HttpInvokerProxy that posts invocations to the
externalURL. This proxy will be associated with a naming JMX invoker
given by the jmxInvokerName.
*/
Invoker delegateInvoker = createInvoker();
Integer nameHash = new Integer(jmxInvokerName.hashCode());
log.debug("Bound delegate: "+delegateInvoker
+" for invoker="+jmxInvokerName);
/* Create a binding betweeh the invoker name hash and the jmx name
This is used by the HttpInvoker to map from the Invocation ObjectName
hash value to the target JMX ObjectName.
*/
Registry.bind(nameHash, jmxInvokerName);
Object cacheID = null;
String proxyBindingName = null;
Class[] ifaces = {exportedInterface};
/* Initialize interceptorClasses with default client interceptor list
if no client interceptor configuration was provided */
if( interceptorClasses == null )
interceptorClasses = defineDefaultInterceptors();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
GenericProxyFactory proxyFactory = new GenericProxyFactory();
theProxy = proxyFactory.createProxy(cacheID, jmxInvokerName,
delegateInvoker, jndiName, proxyBindingName, interceptorClasses,
loader, ifaces);
log.debug("Created HttpInvokerProxy for invoker="+jmxInvokerName
+", nameHash="+nameHash);
if( jndiName != null )
{
InitialContext iniCtx = new InitialContext();
Util.bind(iniCtx, jndiName, theProxy);
log.debug("Bound proxy under jndiName="+jndiName);
}
}
// in src/main/java/org/jboss/invocation/http/server/HttpProxyFactory.java
protected void stopService() throws Exception
{
Integer nameHash = new Integer(jmxInvokerName.hashCode());
Registry.unbind(jmxInvokerName);
Registry.unbind(nameHash);
if( jndiName != null )
{
InitialContext iniCtx = new InitialContext();
Util.unbind(iniCtx, jndiName);
}
}
// in src/main/java/org/jboss/invocation/http/server/HttpProxyFactory.java
protected Invoker createInvoker() throws Exception
{
checkInvokerURL();
HttpInvokerProxy delegateInvoker = new HttpInvokerProxy(invokerURL);
return delegateInvoker;
}
// in src/main/java/org/jboss/invocation/jrmp/server/JRMPProxyFactory.java
public void setClientInterceptors(Element config) throws Exception
{
this.interceptorConfig = config;
Iterator interceptorElements = MetaData.getChildrenByTagName(interceptorConfig, "interceptor");
ClassLoader loader = Thread.currentThread().getContextClassLoader();
interceptorClasses.clear();
while( interceptorElements != null && interceptorElements.hasNext() )
{
Element ielement = (Element) interceptorElements.next();
String className = null;
className = MetaData.getElementContent(ielement);
Class clazz = loader.loadClass(className);
interceptorClasses.add(clazz);
log.debug("added interceptor type: "+clazz);
}
}
// in src/main/java/org/jboss/invocation/jrmp/server/JRMPProxyFactory.java
public Object invoke(Invocation mi) throws Exception
{
final boolean remoteInvocation = mi instanceof MarshalledInvocation;
if(remoteInvocation)
{
((MarshalledInvocation)mi).setMethodMap(methodMap);
}
final Object result;
if(invokeTargetMethod)
{
String signature[] = (String[])signatureMap.get(mi.getMethod());
result = server.invoke(targetName, mi.getMethod().getName(), mi.getArguments(), signature);
}
else
{
result = server.invoke(targetName, "invoke", new Object[]{mi}, Invocation.INVOKE_SIGNATURE);
}
return result;
}
// in src/main/java/org/jboss/invocation/jrmp/server/JRMPProxyFactory.java
protected void startService() throws Exception
{
/* Create a binding between the invoker name hash and the jmx name
This is used by the Invoker to map from the Invocation ObjectName
hash value to the target JMX ObjectName.
*/
Integer nameHash = new Integer(getServiceName().hashCode());
Registry.bind(nameHash, getServiceName());
// Create the service proxy
Object cacheID = null;
String proxyBindingName = null;
Class[] ifaces = exportedInterfaces;
ClassLoader loader = Thread.currentThread().getContextClassLoader();
createProxy(cacheID, proxyBindingName, loader, ifaces);
log.debug("Created JRMPPRoxy for service="+targetName
+", nameHash="+nameHash+", invoker="+invokerName);
if( jndiName != null )
{
InitialContext iniCtx = new InitialContext();
Util.rebind(iniCtx, jndiName, theProxy);
log.debug("Bound proxy under jndiName="+jndiName);
}
for(int i = 0; i < exportedInterfaces.length; ++i)
{
final Method[] methods = exportedInterfaces[i].getMethods();
for(int j = 0; j < methods.length; ++j)
{
methodMap.put(new Long(MarshalledInvocation.calculateHash(methods[j])), methods[j]);
String signature[];
final Class[] types = methods[j].getParameterTypes();
if(types == null || types.length == 0)
{
signature = null;
}
else
{
signature = new String[types.length];
for(int typeInd = 0; typeInd < types.length; ++typeInd)
{
signature[typeInd] = types[typeInd].getName();
}
}
signatureMap.put(methods[j], signature);
}
}
}
// in src/main/java/org/jboss/invocation/jrmp/server/JRMPProxyFactory.java
protected void stopService() throws Exception
{
Integer nameHash = new Integer(getServiceName().hashCode());
Registry.unbind(nameHash);
if( jndiName != null )
{
InitialContext iniCtx = new InitialContext();
Util.unbind(iniCtx, jndiName);
}
this.theProxy = null;
}
// in src/main/java/org/jboss/invocation/jrmp/server/JRMPProxyFactory.java
protected void destroyService() throws Exception
{
interceptorClasses.clear();
}
// in src/main/java/org/jboss/invocation/jrmp/server/JRMPProxyFactory.java
protected void rebind() throws Exception
{
log.debug("(re-)Binding " + jndiName);
Util.rebind(new InitialContext(), jndiName, theProxy);
}
// in src/main/java/org/jboss/invocation/InvokerInterceptor.java
public Object invoke(Invocation invocation)
throws Exception
{
// optimize if calling another bean in same server VM
if (isLocal(invocation))
return invokeLocal(invocation);
else
return invokeInvoker(invocation);
}
// in src/main/java/org/jboss/invocation/InvokerInterceptor.java
protected Object invokeLocal(Invocation invocation) throws Exception
{
return localInvoker.invoke(invocation);
}
// in src/main/java/org/jboss/invocation/InvokerInterceptor.java
protected Object invokeMarshalled(Invocation invocation) throws Exception
{
MarshalledInvocation mi = new MarshalledInvocation(invocation);
MarshalledValue copy = new MarshalledValue(mi);
Invocation invocationCopy = (Invocation) copy.get();
// copy the Tx
Transaction tx = invocation.getTransaction();
invocationCopy.setTransaction(tx);
try
{
Object rtnValue = localInvoker.invoke(invocationCopy);
MarshalledValue mv = new MarshalledValue(rtnValue);
return mv.get();
}
catch(Throwable t)
{
MarshalledValue mv = new MarshalledValue(t);
Throwable t2 = (Throwable) mv.get();
if( t2 instanceof Exception )
throw (Exception) t2;
else
throw new UndeclaredThrowableException(t2);
}
}
// in src/main/java/org/jboss/invocation/InvokerInterceptor.java
protected Object invokeLocalMarshalled(Invocation invocation) throws Exception
{
IMarshalledValue value = createMarshalledValueForCallByValue(invocation.getArguments());
MarshalledInvocation invocationCopy = createInvocationCopy(invocation, value);
// copy the Tx
Transaction tx = invocation.getTransaction();
invocationCopy.setTransaction(tx);
try
{
Object rtnValue = localInvoker.invoke(invocationCopy);
IMarshalledValue mv = createMarshalledValueForCallByValue(rtnValue);
return mv.get();
}
catch(Throwable t)
{
IMarshalledValue mv = SerializationStreamFactory.getManagerInstance().createdMarshalledValue(t);
Throwable t2 = (Throwable) mv.get();
if( t2 instanceof Exception )
throw (Exception) t2;
else
throw new UndeclaredThrowableException(t2);
}
}
// in src/main/java/org/jboss/invocation/InvokerInterceptor.java
protected Object invokeInvoker(Invocation invocation) throws Exception
{
InvocationContext ctx = invocation.getInvocationContext();
Invoker invoker = ctx.getInvoker();
return invoker.invoke(invocation);
}
// in src/main/java/org/jboss/invocation/local/LocalInvoker.java
protected void createService() throws Exception
{
// note on design: We need to call it ourselves as opposed to
// letting the client InvokerInterceptor look it
// up through the use of Registry, the reason being including
// the classes in the client.
// If we move to a JNDI format (with local calls) for the
// registry we could remove the call below
InvokerInterceptor.setLocal(this);
Registry.bind(serviceName, this);
}
// in src/main/java/org/jboss/invocation/local/LocalInvoker.java
protected void startService() throws Exception
{
InitialContext ctx = new InitialContext();
try
{
/**
* FIXME marcf: what is this doing here?
*/
TransactionManager tm = (TransactionManager) ctx.lookup("java:/TransactionManager");
TransactionInterceptor.setTransactionManager(tm);
}
finally
{
ctx.close();
}
log.debug("Local invoker for JMX node started");
}
// in src/main/java/org/jboss/invocation/local/LocalInvoker.java
public Object invoke(Invocation invocation) throws Exception
{
ClassLoader oldCl = TCLAction.UTIL.getContextClassLoader();
ObjectName mbean = (ObjectName) Registry.lookup((Integer) invocation.getObjectName());
try
{
Object[] args = {invocation};
Object rtnValue = serverAction.invoke(mbean, "invoke", args,
Invocation.INVOKE_SIGNATURE);
return rtnValue;
}
catch (Exception e)
{
e = (Exception) JMXExceptionDecoder.decode(e);
if (log.isTraceEnabled())
log.trace("Failed to invoke on mbean: " + mbean, e);
throw e;
}
finally
{
TCLAction.UTIL.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/invocation/local/LocalInvoker.java
public Object run() throws Exception
{
Object rtnValue = server.invoke(target, method, args, sig);
return rtnValue;
}
// in src/main/java/org/jboss/invocation/local/LocalInvoker.java
Object invoke(ObjectName target, String method, Object[] args, String[] sig)
throws Exception
{
SecurityManager sm = System.getSecurityManager();
Object rtnValue = null;
if( sm == null )
{
// Direct invocation on MBeanServer
rtnValue = server.invoke(target, method, args, sig);
}
else
{
try
{
// Encapsulate the invocation in a PrivilegedExceptionAction
MBeanServerAction action = new MBeanServerAction(target, method, args, sig);
rtnValue = AccessController.doPrivileged(action);
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
throw ex;
}
}
return rtnValue;
}
// in src/main/java/org/jboss/invocation/unified/interfaces/UnifiedInvokerProxy.java
public String getServerHostName() throws Exception
{
if(locator != null)
{
return locator.getHost();
}
else
{
return null;
}
}
// in src/main/java/org/jboss/invocation/unified/interfaces/UnifiedInvokerProxy.java
public Object invoke(Invocation invocation) throws Exception
{
Object response = null;
// Earlier versions of InvokerLocator don't have a findSerializationType() method.
try
{
invocation.getInvocationContext().setValue("SERIALIZATION_TYPE",locator.findSerializationType());
}
catch (NoSuchMethodError e)
{
invocation.getInvocationContext().setValue("SERIALIZATION_TYPE", "java");
}
try
{
response = client.invoke(invocation, null);
if(response instanceof Exception)
{
throw ((Exception) response);
}
if(response instanceof MarshalledObject)
{
return ((MarshalledObject) response).get();
}
if (response instanceof IMarshalledValue)
{
return ((IMarshalledValue)response).get();
}
return response;
}
catch(RemoteException aex)
{
// per Jira issue JBREM-61
if(strictRMIException)
{
throw new ServerException(aex.getMessage(), aex);
}
else
{
throw aex;
}
}
catch(Throwable throwable)
{
// this is somewhat of a hack as remoting throws throwable,
// so will let Exception types bubble up, but if Throwable type,
// then have to wrap in new Exception, as this is the signature
// of this invoke method.
if(throwable instanceof Exception)
{
throw (Exception) throwable;
}
throw new Exception(throwable);
}
}
// in src/main/java/org/jboss/invocation/unified/interfaces/UnifiedInvokerProxy.java
protected Client createClient(InvokerLocator locator, String subSystem) throws Exception
{
return new Client(locator, subSystem);
}
// in src/main/java/org/jboss/invocation/unified/server/UnifiedInvoker.java
protected void createService() throws Exception
{
if(connector != null)
{
try
{
connector.addInvocationHandler(getSubSystem(), this);
}
catch(Exception e)
{
log.error("Error adding unified invoker as handler upon connector being set.", e);
}
}
}
// in src/main/java/org/jboss/invocation/unified/server/UnifiedInvoker.java
protected void startService() throws Exception
{
log.debug("Starting unified invoker service.");
InvokerLocator locator = null;
if(serverInvoker != null)
{
locator = serverInvoker.getLocator();
if(!serverInvoker.isStarted())
{
serverInvoker.start();
}
}
else if(connector != null)
{
locator = connector.getLocator();
}
else
{
/**
* This will happen in one of two scenarios. One, the unified invoker was not declared in as
* service before the connector AND was not specified as the handler within the connector config.
* Two, the unified invoker service config did not use the proxy-type attribute within the depends
* tag to have the container set the connector upon creating the unified invoker.
*/
log.error("Error referencing either remoting connector or server invoker to be used. " +
"Please check configuration to make sure proper dependancies are set.");
throw new RuntimeException("Error getting locator because server invoker is null.");
}
proxy = new UnifiedInvokerProxy(locator, strictRMIException);
jmxBind();
}
// in src/main/java/org/jboss/invocation/unified/server/UnifiedInvoker.java
public void stopService() throws Exception
{
// JBAS-5590 -- the serverInvoker is a shared resource and shouldn't
// be stopped just because we don't want it any more
// if(serverInvoker != null)
// {
// serverInvoker.stop();
// }
}
// in src/main/java/org/jboss/client/AppClientMain.java
public static void main(String[] args)
throws Exception
{
log.debug("System Properties");
Properties sysprops = System.getProperties();
for (Object key : sysprops.keySet())
log.debug(" " + key + "=" + sysprops.getProperty((String) key));
// read the client class from args
String clientClass = null;
String clientName = null;
ArrayList<String> newArgs = new ArrayList<String>();
String[] launchers = DEFAULT_LAUNCHERS;
for (int i = 0; i < args.length; i++)
{
String arg = args[i];
log.debug("arg=" + arg);
if( arg.equals(JBOSS_CLIENT_PARAM) )
{
clientClass = args[i+1];
i ++;
}
else if( arg.equals(J2EE_CLIENT_PARAM) )
{
/* Set the j2ee.client system property so the AppContextFactory
sees what name the client app JNDI enc is bound under
*/
clientName = args[i+1];
System.setProperty(javaURLContextFactory.J2EE_CLIENT_NAME_PROP, clientName);
log.info(javaURLContextFactory.J2EE_CLIENT_NAME_PROP + "=" + clientName);
i ++;
}
else if( arg.equals(LAUNCHERS_PARAM) )
{
launchers = args[i+1].split(",");
log.info(LAUNCHERS_PARAM + "=" + args[i+1]);
i ++;
}
else
{
newArgs.add(args[i]);
}
}
ClassLoader loader = Thread.currentThread().getContextClassLoader();
if( loader == null )
loader = AppClientMain.class.getClassLoader();
// Look for a manifest Main-Class
if (clientClass == null)
{
clientClass = getMainClassName(loader);
throw new IllegalArgumentException("Neither a Main-Class was found in the manifest, "
+"nor was a " + JBOSS_CLIENT_PARAM + " specified");
}
// If J2EE_CLIENT_NAME_PROP was not specified, look in the jar descriptors
if (clientName == null)
{
clientName = getClientName(loader);
}
String[] mainArgs = new String [newArgs.size()];
newArgs.toArray(mainArgs);
// Try each launcher in the order specified
for(String launcherName : launchers)
{
try
{
Class<AppClientLauncher> launcherClass = (Class<AppClientLauncher>) loader.loadClass(launcherName);
AppClientLauncher launcher = launcherClass.newInstance();
launcher.launch(clientClass, clientName, mainArgs);
break;
}
catch(Throwable t)
{
log.warn("Failed to launch using: "+launcherName, t);
}
}
}
// in src/main/java/org/jboss/client/AppClientMain.java
private static String getClientName(ClassLoader loader)
throws Exception
{
String clientName = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
// Try META-INF/application-client.xml application-client@id first
URL appXmlURL = loader.getResource("META-INF/application-client.xml");
if( appXmlURL != null )
{
InputStream is = appXmlURL.openStream();
Document appXml = builder.parse(is);
is.close();
Element root = appXml.getDocumentElement();
clientName = root.getAttribute("id");
if( clientName != null )
return clientName;
}
// Try META-INF/jboss-client.xml jndi-name
URL jbossXmlURL = loader.getResource("META-INF/jboss-client.xml");
if( appXmlURL != null )
{
InputStream is = jbossXmlURL.openStream();
Document jbossXml = builder.parse(is);
is.close();
Element root = jbossXml.getDocumentElement();
NodeList children = root.getChildNodes();
for(int n = 0; n < children.getLength(); n ++)
{
Node node = children.item(n);
if( node.getLocalName().equals("jndi-name") )
{
clientName = node.getNodeValue();
return clientName;
}
}
}
// TODO: annotations on main class
return null;
}
// in src/main/java/org/jboss/client/AppClientMain.java
private static String getMainClassName(ClassLoader loader)
throws Exception
{
URL mfURL = loader.getResource("META-INF/MANIFEST.MF");
if(mfURL == null)
{
return null;
}
InputStream is = mfURL.openStream();
Manifest mf;
try
{
mf = new Manifest(is);
}
finally
{
is.close();
}
Attributes attrs = mf.getMainAttributes();
String mainClassName = attrs.getValue(Attributes.Name.MAIN_CLASS);
return mainClassName;
}
// in src/main/java/org/jboss/jmx/adaptor/rmi/RMIRemoteMBeanProxy.java
protected RMIAdaptor getRmiAdaptor () throws Exception
{
InitialContext ctx = new InitialContext();
return (RMIAdaptor) ctx.lookup("jmx/invoker/RMIAdaptor");
}
// in src/main/java/org/jboss/jmx/adaptor/rmi/RMIRemoteMBeanProxy.java
public static Object create (final Class intf, final String name, final javax.management.MBeanServer server) throws Exception
{
return create(intf, new ObjectName(name), server);
}
// in src/main/java/org/jboss/jmx/adaptor/rmi/RMIRemoteMBeanProxy.java
public static Object create (final Class intf, final ObjectName name, final javax.management.MBeanServer server) throws Exception
{
return java.lang.reflect.Proxy.newProxyInstance(Thread.currentThread ().getContextClassLoader (),
new Class[] { intf },
new RMIRemoteMBeanProxy(name, server));
}
// in src/main/java/org/jboss/jmx/connector/invoker/SecurityActions.java
static SecurityContext createSecurityContext(final String domain)
throws PrivilegedActionException
{
return (SecurityContext)AccessController.doPrivileged( new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
return SecurityContextFactory.createSecurityContext(domain);
}});
}
// in src/main/java/org/jboss/jmx/connector/invoker/SecurityActions.java
public Object run() throws Exception
{
return SecurityContextFactory.createSecurityContext(domain);
}
// in src/main/java/org/jboss/jmx/connector/invoker/InvokerAdaptorService.java
protected void startService()
throws Exception
{
// Build the interface method map
HashMap tmpMap = new HashMap(61);
for(int n = 0; n < exportedInterfaces.length; n ++)
{
Class iface = exportedInterfaces[n];
Method[] methods = iface.getMethods();
for(int m = 0; m < methods.length; m ++)
{
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
/* Look for a void addNotificationListener(ObjectName name,
RMINotificationListener listener, NotificationFilter filter,
Object handback)
*/
try
{
Class[] sig = {ObjectName.class, RMINotificationListener.class,
NotificationFilter.class, Object.class};
Method addNotificationListener = iface.getMethod(
"addNotificationListener", sig);
addNotificationListeners.add(addNotificationListener);
}
catch(Exception e)
{
log.debug(iface+"No addNotificationListener(ObjectName, RMINotificationListener)");
}
/* Look for a void removeNotificationListener(ObjectName,
RMINotificationListener)
*/
try
{
Class[] sig = {ObjectName.class, RMINotificationListener.class};
Method removeNotificationListener = iface.getMethod(
"removeNotificationListener", sig);
removeNotificationListeners.add(removeNotificationListener);
}
catch(Exception e)
{
log.debug(iface+"No removeNotificationListener(ObjectName, RMINotificationListener)");
}
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
// Place our ObjectName hash into the Registry so invokers can resolve it
Registry.bind(new Integer(serviceName.hashCode()), serviceName);
}
// in src/main/java/org/jboss/jmx/connector/invoker/InvokerAdaptorService.java
protected void stopService()
throws Exception
{
// Remove the method hashses
if( exportedInterfaces != null )
{
for(int n = 0; n < exportedInterfaces.length; n ++)
MarshalledInvocation.removeHashes(exportedInterfaces[n]);
}
marshalledInvocationMapping = null;
remoteListeners.clear();
Registry.unbind(new Integer(serviceName.hashCode()));
}
// in src/main/java/org/jboss/jmx/connector/invoker/InvokerAdaptorService.java
public Object invoke(Invocation invocation)
throws Exception
{
try
{
// Make sure we have the correct classloader before unmarshalling
ClassLoader oldCL = SecurityActions.getContextClassLoader();
ClassLoader newCL = null;
// Get the MBean this operation applies to
ObjectName objectName = (ObjectName) invocation.getValue("JMX_OBJECT_NAME");
if (objectName != null)
{
newCL = server.getClassLoaderFor(objectName);
}
if (newCL != null && newCL != oldCL)
SecurityActions.setContextClassLoader(newCL);
//JBAS-6449: Cache the incoming security context to be retained on exit
SecurityContext previousSecurityContext = SecurityActions.getSecurityContext();
try
{
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation)
{
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
// Invoke the MBeanServer method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Principal principal = invocation.getPrincipal();
Object credential = invocation.getCredential();
Object value = null;
SecurityContext sc = SecurityActions.createSecurityContext(SecurityConstants.DEFAULT_APPLICATION_POLICY);
SecurityActions.setSecurityContext(sc);
// Associate the method
SecurityActions.pushSubjectContext(principal, credential, null);
try
{
if( addNotificationListeners.contains(method) )
{
ObjectName name = (ObjectName) args[0];
RMINotificationListener listener = (RMINotificationListener)
args[1];
NotificationFilter filter = (NotificationFilter) args[2];
Object handback = args[3];
addNotificationListener(name, listener, filter, handback);
}
else if( removeNotificationListeners.contains(method) )
{
ObjectName name = (ObjectName) args[0];
RMINotificationListener listener = (RMINotificationListener)
args[1];
removeNotificationListener(name, listener);
}
else
{
String name = method.getName();
Class[] paramTypes = method.getParameterTypes();
Method mbeanServerMethod = MBeanServer.class.getMethod(name,
paramTypes);
value = mbeanServerMethod.invoke(server, args);
}
}
catch(InvocationTargetException e)
{
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else
throw new UndeclaredThrowableException(t, method.toString());
}
return value;
}
finally
{
// Restore the input security context
SecurityActions.popSubjectContext();
if(previousSecurityContext != null)
SecurityActions.setSecurityContext(previousSecurityContext);
else
SecurityActions.clearSecurityContext();
// Restore the input class loader
if (newCL != null && newCL != oldCL)
SecurityActions.setContextClassLoader(oldCL);
}
}
catch (Throwable t)
{
throw new InvokerAdaptorException(t);
}
}
// in src/main/java/org/jboss/jmx/connector/invoker/SerializableInterceptor.java
public void setPolicyClass(String policyClass) throws Exception
{
try
{
// try to load the policy Class
Class clazz = Thread.currentThread().getContextClassLoader().loadClass(policyClass);
policy = (SerializablePolicy)clazz.newInstance();
}
catch (Exception e) // ClassNotFoundException, IllegalAccessException, InstantiationException
{
// policy class not found. Make a second try using
// the 'org.jboss.jmx.connector.invoker.serializablepolicy.' package prefix
// for the "standard" reponse policies provided with jboss.
// If that fails, too, rethrow the original exception.
try
{
policyClass = "org.jboss.jmx.connector.invoker.serializablepolicy." + policyClass;
Class clazz = Thread.currentThread().getContextClassLoader().loadClass(policyClass);
policy = (SerializablePolicy)clazz.newInstance();
}
catch (Exception inner)
{
throw e;
}
}
}
// in src/main/java/org/jboss/jmx/connector/invoker/AuthorizationInterceptor.java
public void setAuthorizingClass(Class clazz)
throws Exception
{
authenticator = clazz.newInstance();
log.debug("Loaded authenticator: "+authenticator);
Class[] sig = {Principal.class, Subject.class, String.class, String.class};
authorize = clazz.getMethod("authorize", sig);
log.debug("Found authorize(Principal, Subject, String, String)");
}
// in src/main/java/org/jboss/jmx/connector/invoker/AuthorizationInterceptor.java
private void checkAuthorization(Principal caller, String objname, String opname)
throws Exception
{
// Get the active Subject
Subject subject = SecurityActions.getActiveSubject();
if( subject == null )
throw new SecurityException("No active Subject found, add th AuthenticationInterceptor");
//We will try to use the authorizing class
try
{
Object[] args = {caller, subject, objname, opname};
authorize.invoke(authenticator, args);
}
catch(InvocationTargetException e)
{
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else
throw new UndeclaredThrowableException(t);
}
}
// in src/main/java/org/jboss/jmx/connector/invoker/AuthenticationInterceptor.java
public void setSecurityDomain(String securityDomain) throws Exception
{
this.securityDomain = securityDomain;
}
// in src/main/java/org/jboss/jmx/connector/invoker/MBeanProxyRemote.java
protected void startService() throws Exception
{
if (MBeanProxyExt.remote != null)
throw new IllegalStateException("Remote MBeanServerConnection is already set " + MBeanProxyExt.remote);
Object o = server.getAttribute(mbeanServerConnection, "Proxy");
if (o instanceof MBeanServerConnection == false)
throw new DeploymentException(mbeanServerConnection + " does not define an MBeanServerConnection");
MBeanProxyExt.remote = (MBeanServerConnection) o;
}
// in src/main/java/org/jboss/jmx/connector/invoker/MBeanProxyRemote.java
protected void stopService() throws Exception
{
MBeanProxyExt.remote = null;
}
// in src/main/java/org/jboss/metadata/XmlFileLoader.java
public ApplicationMetaData load(URL alternativeDD) throws Exception
{
URL ejbjarUrl = null;
if (alternativeDD != null)
{
log.debug("Using alternativeDD: " + alternativeDD);
ejbjarUrl = alternativeDD;
}
else
{
ejbjarUrl = getClassLoader().getResource("META-INF/ejb-jar.xml");
}
if (ejbjarUrl == null)
{
throw new DeploymentException("no ejb-jar.xml found");
}
// create the metadata
JBossMetaData realMetaData = new JBossMetaData();
metaData = new ApplicationMetaData(realMetaData);
Document ejbjarDocument = getDocumentFromURL(ejbjarUrl);
// the url may be used to report errors
metaData.setUrl(ejbjarUrl);
metaData.importEjbJarXml(ejbjarDocument.getDocumentElement());
// Load jbossdefault.xml from the default classLoader
// we always load defaults first
// we use the context classloader, because this guy has to know where
// this file is
URL defaultJbossUrl = Thread.currentThread().getContextClassLoader().getResource("standardjboss.xml");
if (defaultJbossUrl == null)
{
throw new DeploymentException("no standardjboss.xml found");
}
Document defaultJbossDocument = null;
try
{
defaultJbossDocument = getDocumentFromURL(defaultJbossUrl);
metaData.setUrl(defaultJbossUrl);
metaData.importJbossXml(defaultJbossDocument.getDocumentElement());
}
catch (Exception ex)
{
log.error("failed to load standardjboss.xml. There could be a syntax error.", ex);
throw ex;
}
// Load jboss.xml
// if this file is provided, then we override the defaults
try
{
URL jbossUrl = getClassLoader().getResource("META-INF/jboss.xml");
if (jbossUrl != null)
{
Document jbossDocument = getDocumentFromURL(jbossUrl);
metaData.setUrl(jbossUrl);
metaData.importJbossXml(jbossDocument.getDocumentElement());
}
}
catch (Exception ex)
{
log.error("failed to load jboss.xml. There could be a syntax error.", ex);
throw ex;
}
return metaData;
}
// in src/main/java/org/jboss/jms/jndi/JMSProviderLoader.java
protected void startService() throws Exception
{
// validate the configuration
if (queueFactoryRef == null)
throw new DeploymentException("missing required attribute: QueueFactoryRef");
if (topicFactoryRef == null)
throw new DeploymentException("missing required attribute: TopicFactoryRef");
Class cls = Thread.currentThread().getContextClassLoader().loadClass(providerAdapterClass);
providerAdapter = (JMSProviderAdapter) cls.newInstance();
providerAdapter.setName(providerName);
providerAdapter.setProperties(properties);
providerAdapter.setFactoryRef(factoryRef);
providerAdapter.setQueueFactoryRef(queueFactoryRef);
providerAdapter.setTopicFactoryRef(topicFactoryRef);
InitialContext context = new InitialContext();
try
{
// Bind in JNDI
if (jndiName == null)
{
String name = providerAdapter.getName();
jndiName = "java:/" + name;
}
bind(context, jndiName, providerAdapter);
log.debug("Bound adapter to " + jndiName);
}
finally
{
context.close();
}
}
// in src/main/java/org/jboss/jms/jndi/JMSProviderLoader.java
protected void stopService() throws Exception
{
InitialContext context = new InitialContext();
try
{
// Unbind from JNDI
String name = providerAdapter.getName();
String jndiname = "java:/" + name;
context.unbind(jndiname);
log.debug("unbound adapter " + name + " from " + jndiname);
}
finally
{
context.close();
}
}
// in src/main/java/org/jboss/jms/recovery/XAResourceWrapper.java
protected XAResource connect() throws Exception
{
// Do we already have a valid delegate?
synchronized (lock)
{
if (delegate != null)
return delegate;
}
// Create the connection
XAConnection xaConnection = getConnectionFactory().createXAConnection();
synchronized (lock)
{
connection = xaConnection;
}
// Retrieve the delegate XAResource
try
{
XASession session = connection.createXASession();
XAResource result = session.getXAResource();
synchronized (lock)
{
delegate = result;
}
return delegate;
}
catch (Exception e)
{
close();
throw e;
}
}
// in src/main/java/org/jboss/jms/recovery/XAResourceWrapper.java
protected XAConnectionFactory getConnectionFactory() throws Exception
{
// Get the JMS Provider Adapter
if (providerName == null)
throw new IllegalArgumentException("Null provider name");
String providerAdapterJNDI = providerName;
if (providerAdapterJNDI.startsWith("java:") == false)
providerAdapterJNDI = "java:" + providerAdapterJNDI;
Context ctx = new InitialContext();
JMSProviderAdapter adapter = (JMSProviderAdapter) Util.lookup(providerAdapterJNDI, JMSProviderAdapter.class);
// Determine the XAConnectionFactory name
String connectionFactoryRef = adapter.getFactoryRef();
if (connectionFactoryRef == null)
throw new IllegalStateException("Provider '" + providerName + "' has no FactoryRef");
// Lookup the connection factory
ctx = adapter.getInitialContext();
try
{
return (XAConnectionFactory) Util.lookup(ctx, connectionFactoryRef, XAConnectionFactory.class);
}
finally
{
ctx.close();
}
}
// in src/main/java/org/jboss/deployment/OptAnnotationMetaDataDeployer.java
protected void processMetaData(VFSDeploymentUnit unit, WebMetaData webMetaData, ApplicationClientMetaData clientMetaData, List<VirtualFile> classpath) throws Exception
{
AnnotationFinder<AnnotatedElement> finder = new DefaultAnnotationFinder<AnnotatedElement>();
// don't do webMetaData anymore (rev 96033)
String mainClassName = getMainClassName(unit);
if (mainClassName != null && mainClassName.length() > 0)
processJBossClientMetaData(unit, finder, mainClassName);
else
processJBossMetaData(unit, finder);
}
// in src/main/java/org/jboss/deployment/WebAppFragmentParsingDeployer.java
protected void init(VFSDeploymentUnit unit, WebFragmentMetaData metaData, VirtualFile file) throws Exception
{
unit.addAttachment(WebFragmentMetaData.class.getName() + ":" + file.getPathNameRelativeTo(unit.getRoot()), metaData, getOutput());
}
// in src/main/java/org/jboss/deployment/MappedReferenceMetaDataResolverDeployer.java
protected void resolve(ContainerDependencyMetaData cdmd, DeploymentUnit unit,
Map<String, ContainerDependencyMetaData> endpointMap,
Environment env,
DeploymentEndpointResolver resolver,
List<String> unresolvedRefs)
throws Exception
{
if(env == null)
return;
AnnotatedEJBReferencesMetaData annotatedRefs = env.getAnnotatedEjbReferences();
resolveEjbAnnotatedRefs(cdmd, unit, endpointMap, annotatedRefs, resolver, unresolvedRefs);
EJBLocalReferencesMetaData localRefs = env.getEjbLocalReferences();
resolveEjbLocalRefs(cdmd, unit, endpointMap, localRefs, resolver, unresolvedRefs);
EJBReferencesMetaData ejbRefs = env.getEjbReferences();
resolveEjbRefs(cdmd, unit, endpointMap, ejbRefs, resolver, unresolvedRefs);
MessageDestinationReferencesMetaData msgRefs = env.getMessageDestinationReferences();
resolveMsgRefs(cdmd, unit, endpointMap, msgRefs, resolver, unresolvedRefs);
// TODO, other references
}
// in src/main/java/org/jboss/deployment/MappedReferenceMetaDataResolverDeployer.java
protected void resolve(DeploymentUnit unit, Map<String, ContainerDependencyMetaData> endpointMap,
JBossEnterpriseBeansMetaData beans,
DeploymentEndpointResolver resolver,
List<String> unresolvedPaths)
throws Exception
{
if(beans == null || beans.size() == 0)
return;
String vfsPath = unit.getRelativePath();
for(JBossEnterpriseBeanMetaData bean : beans)
{
// Find the container dependency metadata
String ejbCompID = "ejb/" + vfsPath + "#" + bean.getEjbName();
ContainerDependencyMetaData cdmd = endpointMap.get(ejbCompID);
if(cdmd == null)
throw new IllegalStateException("Failed to find ContainerDependencyMetaData for: "+ejbCompID);
Environment env = bean.getJndiEnvironmentRefsGroup();
resolve(cdmd, unit, endpointMap, env, resolver, unresolvedPaths);
}
}
// in src/main/java/org/jboss/deployment/MappedReferenceMetaDataResolverDeployer.java
protected void resolveEjbLocalRefs(ContainerDependencyMetaData cdmd, DeploymentUnit unit,
Map<String, ContainerDependencyMetaData> endpointMap,
EJBLocalReferencesMetaData localRefs,
DeploymentEndpointResolver resolver,
List<String> unresolvedRefs)
throws Exception
{
if(localRefs == null)
return;
String vfsContext = unit.getRelativePath();
ClassLoader loader = unit.getClassLoader();
for(EJBLocalReferenceMetaData ref : localRefs)
{
if (ref.getIgnoreDependency() != null)
{
log.debug("IGNORING <ejb-ref> DEPENDENCY: " + ref);
return;
}
String link = ref.getLink();
String mappedName = ref.getMappedName();
// Use mapped name first
if(mappedName == null || mappedName.length() == 0)
{
ContainerDependencyMetaData target = null;
if(link != null)
{
EndpointInfo info = resolver.getEndpointInfo(link, EndpointType.EJB, vfsContext);
if(info != null)
{
target = endpointMap.get(info.getComponentKey());
}
else
{
/* A non-local link without a # jar target. This is allowed
for java ee clients so we have to search all ejb deployments.
First get the vfspaths of the ejb deploymens.
*/
List<String> ejbPaths = getEjbDeploymentPaths(unit);
for(String path : ejbPaths)
{
EndpointInfo altInfo = resolver.getEndpointInfo(link, EndpointType.EJB, path);
if(altInfo != null)
target = endpointMap.get(altInfo.getComponentKey());
if(target != null)
break;
}
}
}
if(target == null && ref.getLocal() != null)
{
// Try the local interface type
target = resolveEjbInterface(ref.getLocal(), unit,
endpointMap, resolver);
}
if(target == null)
unresolvedRefs.add(cdmd.getComponentID()+":"+ref);
else
{
// Need to look at the local jndi name
String localInterface = ref.getLocal();
JBossEnterpriseBeanMetaData md = target.getBeanMetaData();
/*
* If for a Session bean we've got a reference to an EJB2.x
* Local Component interface, stop processing because these
* are not bound in JNDI (only accessible via LocalHome.create()
*/
// Session EJB?
boolean useDefaultProxy = false;
if(md.isSession())
{
// Cast
JBossSessionBeanMetaData smd = (JBossSessionBeanMetaData)md;
// Get the name of the Component Local Interface
String ejb2xLocalInterface = smd.getLocal();
// If the ejb-ref is to a EJB2.x Local Component Interface
if(localInterface.equals(ejb2xLocalInterface))
{
// Use the default proxy
useDefaultProxy = true;
}
}
// Get ejb-jar Metadata
JBossMetaData ejbJarMd = md.getEnterpriseBeansMetaData().getEjbJarMetaData();
// Resolve a local JNDI Name based on Spec type
String localJndiName = null;
if (ejbJarMd.isEJB3x())
{
if (md.isSession() || md.isService())
{
SessionBeanJNDINameResolver sessionBeanJNDINameResolver = JNDIPolicyBasedJNDINameResolverFactory.getJNDINameResolver((JBossSessionBeanMetaData) md, this.defaultJNDIBindingPolicy);
if (useDefaultProxy)
{
localJndiName = sessionBeanJNDINameResolver
.resolveLocalBusinessDefaultJNDIName((JBossSessionBeanMetaData) md);
}
else
{
localJndiName = sessionBeanJNDINameResolver.resolveJNDIName((JBossSessionBeanMetaData) md, localInterface);
}
}
else if (md.isEntity())
{
EntityBeanJNDINameResolver entityBeanJNDINameResolver = JNDIPolicyBasedJNDINameResolverFactory.getJNDINameResolver((JBossEntityBeanMetaData) md, this.defaultJNDIBindingPolicy);
localJndiName = entityBeanJNDINameResolver.resolveJNDIName((JBossEntityBeanMetaData) md, localInterface);
}
}
else
{
localJndiName = md.determineLocalJndiName();
}
// If we've got a resolved JNDI Name
if (localJndiName != null)
{
// Set it and forget it!
// http://en.wikipedia.org/wiki/Ron_Popeil
ref.setResolvedJndiName(localJndiName);
}
// Add the dependency
cdmd.addDependency(target);
}
}
else
{
// Create a JNDI dependency
ref.setResolvedJndiName(mappedName);
JndiDependencyMetaData jdmd = new JndiDependencyMetaData(mappedName, loader);
cdmd.addJndiDependency(jdmd);
}
}
}
// in src/main/java/org/jboss/deployment/MappedReferenceMetaDataResolverDeployer.java
protected void resolveEjbRefs(ContainerDependencyMetaData cdmd, DeploymentUnit unit,
Map<String, ContainerDependencyMetaData> endpointMap,
EJBReferencesMetaData ejbRefs,
DeploymentEndpointResolver resolver,
List<String> unresolvedRefs)
throws Exception
{
if(ejbRefs == null)
return;
String vfsContext = unit.getRelativePath();
ClassLoader loader = unit.getClassLoader();
for(EJBReferenceMetaData ref : ejbRefs)
{
if (ref.getIgnoreDependency() != null)
{
log.debug("IGNORING <ejb-ref> DEPENDENCY: " + ref);
return;
}
String link = ref.getLink();
String mappedName = ref.getMappedName();
// Use mapped name first
if(mappedName == null || mappedName.length() == 0)
{
ContainerDependencyMetaData target = null;
if(link != null)
{
EndpointInfo info = resolver.getEndpointInfo(link, EndpointType.EJB, vfsContext);
if(info != null)
{
target = endpointMap.get(info.getComponentKey());
}
else
{
/* A non-local link without a # jar target. This is allowed
for java ee clients so we have to search all ejb deployments.
First get the vfspaths of the ejb deploymens.
*/
List<String> ejbPaths = getEjbDeploymentPaths(unit);
for(String path : ejbPaths)
{
EndpointInfo altInfo = resolver.getEndpointInfo(link, EndpointType.EJB, path);
if(altInfo != null)
target = endpointMap.get(altInfo.getComponentKey());
if(target != null)
break;
}
}
if(target == null)
{
unresolvedRefs.add(cdmd.getComponentID()+":"+ref);
continue;
}
}
if(target == null && ref.getRemote() != null)
{
// Try the local interface type
target = resolveEjbInterface(ref.getRemote(), unit,
endpointMap, resolver);
}
if(target == null)
unresolvedRefs.add(cdmd.getComponentID()+":"+ref);
else
{
// Obtain remote interface name
String remoteInterface = ref.getRemote();
// Get Metadata
JBossEnterpriseBeanMetaData md = target.getBeanMetaData();
/*
* If for a Session bean we've got a reference to an EJB2.x
* Remote Component interface, stop processing because these
* are not bound in JNDI (only accessible via Home.create()
*/
// Session EJB?
boolean useDefaultProxy = false;
if(md.isSession())
{
// Cast
JBossSessionBeanMetaData smd = (JBossSessionBeanMetaData)md;
// Get the name of the Component Remote Interface
String ejb2xRemoteInterface = smd.getRemote();
// If the ejb-ref is to a EJB2.x Remote Component Interface
if(remoteInterface.equals(ejb2xRemoteInterface))
{
// Use the default proxy
useDefaultProxy = true;
}
}
// Get ejb-jar metadata
JBossMetaData ejbMarMd = md.getEnterpriseBeansMetaData().getEjbJarMetaData();
// Resolve a JNDI name
String remoteJNDIName = null;
if (ejbMarMd.isEJB3x())
{
if (md.isSession() || md.isService())
{
SessionBeanJNDINameResolver sessionBeanJNDINameResolver = JNDIPolicyBasedJNDINameResolverFactory.getJNDINameResolver((JBossSessionBeanMetaData) md, this.defaultJNDIBindingPolicy);
if (useDefaultProxy)
{
remoteJNDIName = sessionBeanJNDINameResolver.resolveRemoteBusinessDefaultJNDIName((JBossSessionBeanMetaData) md);
}
else
{
remoteJNDIName = sessionBeanJNDINameResolver.resolveJNDIName((JBossSessionBeanMetaData) md, remoteInterface);
}
}
else if (md.isEntity())
{
EntityBeanJNDINameResolver entityBeanJNDINameResolver = JNDIPolicyBasedJNDINameResolverFactory.getJNDINameResolver((JBossEntityBeanMetaData) md, this.defaultJNDIBindingPolicy);
remoteJNDIName = entityBeanJNDINameResolver.resolveJNDIName((JBossEntityBeanMetaData) md, remoteInterface);
}
}
else
{
remoteJNDIName = md.determineJndiName();
}
// If we've got a resolved name
if(remoteJNDIName != null)
{
// Set it
ref.setResolvedJndiName(remoteJNDIName);
}
// Add the dependency
cdmd.addDependency(target);
}
}
else
{
// Create a JNDI dependency
ref.setResolvedJndiName(mappedName);
JndiDependencyMetaData jdmd = new JndiDependencyMetaData(mappedName, loader);
cdmd.addJndiDependency(jdmd);
}
}
}
// in src/main/java/org/jboss/deployment/MappedReferenceMetaDataResolverDeployer.java
protected ContainerDependencyMetaData resolveEjbInterface(String iface,
DeploymentUnit unit, Map<String, ContainerDependencyMetaData> endpointMap,
DeploymentEndpointResolver resolver)
throws Exception
{
ClassLoader loader = unit.getClassLoader();
Class<?> ifaceClass = loader.loadClass(iface);
String vfsContext = unit.getRelativePath();
EndpointInfo info = resolver.getEndpointInfo(ifaceClass, EndpointType.EJB, vfsContext);
if(info == null)
throw new IllegalStateException("Failed to find ContainerDependencyMetaData for interface: "+ iface);
ContainerDependencyMetaData cdmd = endpointMap.get(info.getComponentKey());
return cdmd;
}
// in src/main/java/org/jboss/deployment/AppParsingDeployer.java
protected EarMetaData parse(VFSDeploymentUnit unit, VirtualFile file, EarMetaData root) throws Exception
{
EarMetaData ear = super.parse(unit,file, root);
List<DeploymentUnit> children = unit.getChildren();
ModulesMetaData modules = ear.getModules();
if(children != null && modules != null)
{
for(DeploymentUnit child : children)
{
String moduleName = child.getSimpleName();
ModuleMetaData module = modules.get(moduleName);
if(module != null && module.getAlternativeDD() != null)
{
VirtualFile altDDFile = unit.getRoot().getChild(module.getAlternativeDD());
if(altDDFile == null)
throw new IllegalStateException("Failed to locate alternative DD '" + module.getAlternativeDD() + "' in " + unit.getRoot().getPathName());
String attachmentName;
if(module.getType() == ModuleMetaData.ModuleType.Ejb)
attachmentName = EjbJarMetaData.class.getName();
else if(module.getType() == ModuleMetaData.ModuleType.Web)
attachmentName = WebMetaData.class.getName();
else if(module.getType() == ModuleMetaData.ModuleType.Client)
attachmentName = ApplicationClientMetaData.class.getName();
else if(module.getType() == ModuleMetaData.ModuleType.Connector)
attachmentName = "org.jboss.resource.metadata.ConnectorMetaData";
else
throw new IllegalStateException("Expected module types in an EAR are ejb, web, java and connector but got " + module.getType() + " for " + child.getName() + " in " + unit.getName());
child.addAttachment(attachmentName + ".altDD", altDDFile);
if(log.isTraceEnabled())
log.trace("attached alt-dd " + altDDFile + " for module " + child.getSimpleName());
}
}
}
return ear;
}
// in src/main/java/org/jboss/deployment/AnnotationMetaDataDeployer.java
protected void processMetaData(VFSDeploymentUnit unit, WebMetaData webMetaData, ApplicationClientMetaData clientMetaData, List<VirtualFile> classpath) throws Exception
{
String mainClassName = getMainClassName(unit);
Collection<Class<?>> classes = new HashSet<Class<?>>();
Map<VirtualFile, Collection<Class<?>>> classesPerJar = new HashMap<VirtualFile, Collection<Class<?>>>();
for (VirtualFile path : classpath)
{
Collection<Class<?>> currentClasses = getClasses(unit, mainClassName, path);
classesPerJar.put(path, currentClasses);
classes.addAll(currentClasses);
}
if (classes.size() > 0)
{
AnnotationFinder<AnnotatedElement> finder = new DefaultAnnotationFinder<AnnotatedElement>();
if (webMetaData != null)
processJBossWebMetaData(unit, finder, classesPerJar);
else if (clientMetaData != null || mainClassName != null)
processJBossClientMetaData(unit, finder, classes);
else
processJBossMetaData(unit, finder, classes);
}
}
// in src/main/java/org/jboss/deployment/TldParsingDeployer.java
protected void init(VFSDeploymentUnit unit, TldMetaData metaData, VirtualFile file) throws Exception
{
unit.addAttachment(TldMetaData.class.getName() + ":" + file.getPathNameRelativeTo(unit.getRoot()), metaData, getOutput());
}
// in src/main/java/org/jboss/deployment/TldParsingDeployer.java
protected TldMetaData parse(VirtualFile file) throws Exception {
if (file == null)
throw new IllegalArgumentException("Null file");
// Implicit TLDs are reserved as the "implicit.tld" name
if (file.getName().equals("implicit.tld")) {
return new TldMetaData();
} else {
return super.parse(file);
}
}
// in src/main/java/org/jboss/naming/client/java/javaURLContextFactory.java
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable env)
throws Exception
{
// Get the j2ee.clientName value
String clientName = (String) env.get(J2EE_CLIENT_NAME_PROP);
if (clientName == null)
{
// Look for the name as a system property
clientName = (String) AccessController.doPrivileged(
new PrivilegedAction()
{
public Object run()
{
try
{
return System.getProperty(J2EE_CLIENT_NAME_PROP);
}
catch (SecurityException e)
{
return null;
}
}
}
);
if (clientName == null)
throw new NamingException("Failed to find j2ee.clientName in jndi env");
}
// in src/main/java/org/jboss/naming/NamingAlias.java
protected void startService() throws Exception
{
if( fromName == null )
throw new IllegalStateException("fromName is null");
if( toName == null )
throw new IllegalStateException("toName is null");
createLinkRef();
}
// in src/main/java/org/jboss/naming/NamingAlias.java
protected void stopService() throws Exception
{
removeLinkRef(fromName);
}
// in src/main/java/org/jboss/naming/ExternalContext.java
protected void startService() throws Exception
{
rebind();
}
// in src/main/java/org/jboss/naming/ExternalContext.java
protected void stopService() throws Exception
{
if( contextInfo.getCacheContext() )
unbind(contextInfo.getJndiName());
}
// in src/main/java/org/jboss/naming/ExternalContext.java
private void rebind() throws Exception
{
Context ctx = contextInfo.newContext();
Context rootCtx = (Context) new InitialContext();
log.debug("ctx="+ctx+", env="+ctx.getEnvironment());
// Get the parent context into which we are to bind
String jndiName = contextInfo.getJndiName();
Name fullName = rootCtx.getNameParser("").parse(jndiName);
log.debug("fullName="+fullName);
Name parentName = fullName;
if( fullName.size() > 1 )
parentName = fullName.getPrefix(fullName.size()-1);
else
parentName = new CompositeName();
log.debug("parentName="+parentName);
Context parentCtx = createContext(rootCtx, parentName);
log.debug("parentCtx="+parentCtx);
Name atomName = fullName.getSuffix(fullName.size()-1);
String atom = atomName.get(0);
boolean cacheContext = contextInfo.getCacheContext();
if( remoteAccess == true )
{
// Bind contextInfo as a Referenceable
parentCtx.rebind(atom, contextInfo);
// Cache the context using NonSerializableFactory to avoid creating
// more than one context for in VM lookups
if( cacheContext == true )
{
// If cacheContext is true we need to wrap the Context in a
// proxy that allows the user to issue close on the lookup
// Context without closing the inmemory Context.
ctx = CachedContext.createProxyContext(ctx);
NonSerializableFactory.rebind(jndiName, ctx);
}
}
else if( cacheContext == true )
{
// Bind a reference to the extern context using
// NonSerializableFactory as the ObjectFactory. The Context must
// be wrapped in a proxy that allows the user to issue close on the
// lookup Context without closing the inmemory Context.
Context proxyCtx = CachedContext.createProxyContext(ctx);
NonSerializableFactory.rebind(rootCtx, jndiName, proxyCtx);
}
else
{
// Bind the contextInfo so that each lookup results in the creation
// of a new Context object. The returned Context must be closed
// by the user to prevent resource leaks.
parentCtx.rebind(atom, contextInfo);
}
}
// in src/main/java/org/jboss/naming/ExternalContext.java
Context newContext() throws Exception
{
// First check the NonSerializableFactory cache
initialContext = (Context) NonSerializableFactory.lookup(jndiName);
// Create the context from the contextClass and contextProps
if( initialContext == null )
initialContext = newContext(contextClass, contextProps);
return initialContext;
}
// in src/main/java/org/jboss/naming/ExternalContext.java
static Context newContext(Class contextClass, Properties contextProps)
throws Exception
{
Context ctx = null;
try
{
ctx = newDefaultContext(contextClass, contextProps);
}
catch(NoSuchMethodException e)
{
ctx = newLdapContext(contextClass, contextProps);
}
return ctx;
}
// in src/main/java/org/jboss/naming/ExternalContext.java
private static Context newDefaultContext(Class contextClass, Properties contextProps)
throws Exception
{
Context ctx = null;
Class[] types = {Hashtable.class};
Constructor ctor = contextClass.getConstructor(types);
Object[] args = {contextProps};
ctx = (Context) ctor.newInstance(args);
return ctx;
}
// in src/main/java/org/jboss/naming/ExternalContext.java
private static Context newLdapContext(Class contextClass, Properties contextProps)
throws Exception
{
Context ctx = null;
Class[] types = {Hashtable.class, Control[].class};
Constructor ctor = contextClass.getConstructor(types);
Object[] args = {contextProps, null};
ctx = (Context) ctor.newInstance(args);
return ctx;
}
// in src/main/java/org/jboss/naming/ExternalContext.java
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment)
throws Exception
{
Reference ref = (Reference) obj;
SerializableInitialContext sic = (SerializableInitialContext) ref.get(0);
return sic.newContext();
}
// in src/main/java/org/jboss/naming/LinkRefPairService.java
protected void startService() throws Exception
{
if (jndiName == null)
throw new DeploymentException("The jndiName is null for LinkRefPair " + getServiceName());
if (remoteJndiName == null)
throw new DeploymentException("The remoteJndiName is null for LinkRefPair " + getServiceName());
if (localJndiName == null)
throw new DeploymentException("The localJndiName is null for LinkRefPair " + getServiceName());
LinkRefPair pair = new LinkRefPair(remoteJndiName, localJndiName);
InitialContext ctx = new InitialContext();
try
{
Util.bind(ctx, jndiName, pair);
}
finally
{
ctx.close();
}
}
// in src/main/java/org/jboss/naming/LinkRefPairService.java
protected void stopService() throws Exception
{
LinkRefPair pair = new LinkRefPair(remoteJndiName, localJndiName);
InitialContext ctx = new InitialContext();
try
{
Util.unbind(ctx, jndiName);
}
finally
{
ctx.close();
}
}
// in src/main/java/org/jboss/naming/java/javaURLContextFactory.java
public Object getObjectInstance(Object obj,
Name name,
Context nameCtx,
Hashtable environment)
throws Exception
{
return new NamingContext(environment, name, root);
}
// in src/main/java/org/jboss/naming/NamingProviderURLWriter.java
public void start() throws Exception
{
establishBootStrapURL();
if (bootstrapUrl != null)
{
File base = null;
if (outputDir == null)
{
if (server != null)
{
base = new File(server.getConfiguration().getServerDataLocation().toURI());
outputDir = base.toURI();
}
}
else
{
base = new File(outputDir);
}
if (base != null)
{
base.mkdirs();
File file = new File(base, getOutputFileName());
if (file.exists())
{
file.delete();
}
PrintWriter writer = null;
try
{
if (log.isTraceEnabled())
{
log.trace("Creating file " + file);
}
file.createNewFile();
file.deleteOnExit();
writer = new PrintWriter(file);
writer.println(bootstrapUrl);
writer.flush();
}
catch (Exception e)
{
handleOutputFileCreationException(file.toURI(), e);
}
finally
{
if (writer != null)
{
writer.close();
}
}
}
else
{
log.warn("No directory specified for " + getOutputFileName() +
" cannot write the naming service url. Please configure either " +
"the 'server' property or the 'outputDir' property.");
}
}
else
{
log.debug("No URLs to write");
}
}
// in src/main/java/org/jboss/naming/NamingProviderURLWriter.java
public void stop() throws Exception
{
if (outputDir != null)
{
String outputFile = "";
try
{
File f = new File(new File(outputDir), getOutputFileName());
outputFile = f.getAbsolutePath();
f.delete();
}
catch (Exception e)
{
log.warn("Failed to delete JNP URL file " + outputFile + " due to " + e);
}
}
}
// in src/main/java/org/jboss/naming/LinkRefPairObjectFactory.java
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception
{
LinkRefPair pair = (LinkRefPair) obj;
String jndiName;
// Local or remote?
boolean local = false;
if (guid.equals(pair.getGUID()))
{
jndiName = pair.getLocalLinkName();
local = true;
}
else
jndiName = pair.getRemoteLinkName();
InitialContext ctx;
if (local || environment == null)
ctx = new InitialContext();
else
ctx = new InitialContext(environment);
return ctx.lookup(jndiName);
}
// in src/main/java/org/jboss/naming/JNDIBinding.java
public Object getValue() throws Exception
{
if( value == null && text != null )
{
// If there is a property editor set, transform text to value
if( editor != null )
{
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class editorClass = loader.loadClass(editor);
PropertyEditor pe = (PropertyEditor) editorClass.newInstance();
pe.setAsText(text);
value = pe.getValue();
}
else if( type != null )
{
PropertyEditor pe = PropertyEditors.getEditor(type);
pe.setAsText(text);
value = pe.getValue();
}
else
{
value = text;
}
}
return value;
}
// in src/main/java/org/jboss/naming/JNDIBindingServiceMgr.java
protected void startService() throws Exception
{
service.addBindings();
}
// in src/main/java/org/jboss/naming/JNDIBindingServiceMgr.java
protected void stopService() throws Exception
{
service.removeBindings();
}
// in src/main/java/org/jboss/naming/HttpNamingContextFactory.java
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable env)
throws Exception
{
Context ctx = getInitialContext(env);
Reference ref = (Reference) obj;
RefAddr addr = ref.get("URL");
String path = (String) addr.getContent();
return ctx.lookup(path);
}
// in src/main/java/org/jboss/naming/JNDIBindingService.java
public void start() throws Exception
{
addBindings();
}
// in src/main/java/org/jboss/naming/JNDIBindingService.java
public void stop() throws Exception
{
removeBindings();
}
// in src/main/java/org/jboss/naming/NamingService.java
public Object getNamingProxy()
throws Exception
{
Object proxy = null;
if(proxyFactory != null)
proxy = proxyFactory.getProxy();
else
proxy = namingMain.getNamingProxy();
return proxy;
}
// in src/main/java/org/jboss/naming/NamingService.java
protected void startService()
throws Exception
{
boolean debug = log.isDebugEnabled();
// Read jndi.properties into system properties
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("jndi.properties");
if (is == null)
throw new RuntimeException("Cannot find jndi.properties, it should be at conf/jndi.properties by default.");
Properties props = new Properties();
try
{
props.load(is);
}
finally
{
is.close();
}
for (Enumeration keys = props.propertyNames(); keys.hasMoreElements(); )
{
String key = (String) keys.nextElement();
String value = props.getProperty(key);
if (debug)
{
log.debug("System.setProperty, key="+key+", value="+value);
}
System.setProperty(key, value);
}
if( proxyFactory != null )
namingMain.setNamingProxy(proxyFactory.getProxy());
if( startNamingBean )
namingMain.start();
// Build the Naming interface method map
HashMap tmpMap = new HashMap(13);
Method[] methods = Naming.class.getMethods();
for(int m = 0; m < methods.length; m ++)
{
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
}
// in src/main/java/org/jboss/naming/NamingService.java
protected void stopService()
throws Exception
{
if(startNamingBean)
{
namingMain.stop();
log.debug("JNP server stopped");
}
}
// in src/main/java/org/jboss/naming/NamingService.java
public void createAlias(String fromName, String toName) throws Exception
{
Util.createLinkRef(fromName, toName);
log.info("Created alias " + fromName + "->" + toName);
}
// in src/main/java/org/jboss/naming/NamingService.java
public void removeAlias(String name) throws Exception
{
log.info("Removing alias " + name);
Util.removeLinkRef(name);
}
// in src/main/java/org/jboss/naming/NamingService.java
public Object invoke(Invocation invocation) throws Exception
{
Naming theServer = namingMain.getNamingInstance();
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation)
{
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
// Invoke the Naming method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try
{
value = method.invoke(theServer, args);
}
catch(InvocationTargetException e)
{
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else
throw new UndeclaredThrowableException(t, method.toString());
}
return value;
}
// in src/main/java/org/jboss/naming/interceptors/ProxyFactoryInterceptor.java
private void initNamingProxy()
throws Exception
{
if( proxy != null )
return;
ObjectName proxyFactory = new ObjectName(proxyName);
MBeanServer server = MBeanServerLocator.locateJBoss();
proxy = (Naming) server.getAttribute(proxyFactory, "Proxy");
}
// in src/main/java/org/jboss/naming/JndiBinder.java
public void start() throws Exception
{
InitialContext ctx1 = null;
if (properties != null)
{
ctx1 = new InitialContext(properties);
}
else ctx1 = new InitialContext();
InitialContext ctx = ctx1;
try
{
if (serializable)
{
Util.rebind(ctx, bindTo, target);
}
else
{
NonSerializableFactory.rebind(ctx, bindTo, target);
}
} catch (NamingException e)
{
NamingException namingException = new NamingException("Could not bind JndiBinder service into JNDI under jndiName:" + ctx.getNameInNamespace() + "/" + bindTo);
namingException.setRootCause(e);
throw namingException;
}
}
// in src/main/java/org/jboss/naming/JndiBinder.java
public void stop() throws Exception
{
InitialContext ctx1 = null;
if (properties != null)
{
ctx1 = new InitialContext(properties);
}
else ctx1 = new InitialContext();
InitialContext ctx = ctx1;
if (serializable)
{
Util.unbind(ctx, bindTo);
}
else
{
NonSerializableFactory.unbind(bindTo);
}
}
// in src/main/java/org/jboss/tm/usertx/client/ClientUserTransactionObjectFactory.java
public Object getObjectInstance(Object obj, Name name,
Context nameCtx, Hashtable environment)
throws Exception
{
Reference ref = (Reference)obj;
if (!ref.getClassName().equals(ClientUserTransaction.class.getName()))
return null;
return getUserTransaction();
}
// in src/main/java/org/jboss/tm/usertx/server/ClientUserTransactionService.java
public Object invoke(Invocation invocation) throws Exception
{
// Set the method hash to Method mapping
if (invocation instanceof MarshalledInvocation)
{
MarshalledInvocation mi = (MarshalledInvocation) invocation;
mi.setMethodMap(marshalledInvocationMapping);
}
// Invoke the method via reflection
Method method = invocation.getMethod();
Object[] args = invocation.getArguments();
Object value = null;
try
{
if( UserTransactionSessionFactory.class.isAssignableFrom(method.getDeclaringClass()) )
{
// Just return the UserTransactionSession proxy as its stateless
value = txProxy;
}
else if( method.getName().equals("begin") )
{
// Begin a new transaction
Integer timeout = (Integer) args[0];
UserTransactionSession session = UserTransactionSessionImpl.getInstance();
value = session.begin(timeout.intValue());
}
else if( method.getName().equals("destroy"))
{
/* We do nothing as the tx will timeout and the tx map is shared
across all sessions as we have no association with the txs
a given client has started.
*/
}
else
{
UserTransactionSession session = UserTransactionSessionImpl.getInstance();
value = method.invoke(session, args);
}
}
catch(InvocationTargetException e)
{
Throwable t = e.getTargetException();
if( t instanceof Exception )
throw (Exception) t;
else
throw new UndeclaredThrowableException(t, method.toString());
}
return value;
}
// in src/main/java/org/jboss/tm/usertx/server/ClientUserTransactionService.java
protected void startService()
throws Exception
{
Context ctx = new InitialContext();
// Bind the in VM UserTransaction interface
ctx.bind(JNDI_NAME, ClientUserTransaction.getSingleton());
// Get the UserTransactionSession proxy
txProxy = getServer().getAttribute(txProxyName, "Proxy");
// Build the UserTransactionSession interface method map
HashMap tmpMap = new HashMap(13);
Method[] methods = UserTransactionSession.class.getMethods();
for(int m = 0; m < methods.length; m ++)
{
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
// Add the UserTransactionSessionFactory interface method map
methods = UserTransactionSessionFactory.class.getMethods();
for(int m = 0; m < methods.length; m ++)
{
Method method = methods[m];
Long hash = new Long(MarshalledInvocation.calculateHash(method));
tmpMap.put(hash, method);
}
marshalledInvocationMapping = Collections.unmodifiableMap(tmpMap);
// Place our ObjectName hash into the Registry so invokers can resolve it.
// We need this for the HA Proxy case where the only the target service
// is added to the registry, which is how it should be.
// In the non HA Proxy case, JRMPProxyFactory acts both as a proxy factory
// and proxy which is conceptually wrong, hence this is an extra step in
// that case.
Registry.bind(new Integer(serviceName.hashCode()), serviceName);
}
// in src/main/java/org/jboss/ejb/txtimer/SecurityActions.java
static SecurityContext createSecurityContext(final String securityDomain)
throws PrivilegedActionException
{
return (SecurityContext)AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(securityDomain);
SecurityContextAssociation.setSecurityContext(sc);
return sc;
}
});
}
// in src/main/java/org/jboss/ejb/txtimer/SecurityActions.java
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(securityDomain);
SecurityContextAssociation.setSecurityContext(sc);
return sc;
}
// in src/main/java/org/jboss/ejb/txtimer/DatabasePersistencePolicy.java
public void startService() throws Exception
{
// Get the persistence plugin
if (dbpPluginClassName != null)
{
Class dbpPolicyClass = Thread.currentThread().getContextClassLoader().loadClass(dbpPluginClassName);
dbpPlugin = (DatabasePersistencePlugin)dbpPolicyClass.newInstance();
}
else
{
dbpPlugin = new GeneralPurposeDatabasePersistencePlugin();
}
// init the plugin
if (dbpPlugin instanceof DatabasePersistencePluginExt)
{
// if using the extended plugin interface, initialize the timers table name
((DatabasePersistencePluginExt)dbpPlugin).init(server, dataSource, timersTable);
}
else
{
dbpPlugin.init(server, dataSource);
}
// warn if timers table cannot be set
if (dbpPlugin.getTableName().equals(timersTable) == false)
{
log.warn("Database persistence plugin '" + dbpPluginClassName +
"' uses hardcoded timers table name: '" + dbpPlugin.getTableName());
}
// create the table if needed
dbpPlugin.createTableIfNotExists();
}
// in src/main/java/org/jboss/ejb/txtimer/TimedObjectInvokerImpl.java
public void callTimeout(Timer timer)
throws Exception
{
ClassLoader callerClassLoader = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(container.getClassLoader());
container.pushENC();
try
{
Invocation inv = new Invocation(timedObjectId.getInstancePk(), method, new Object[]{timer}, null, null, null);
inv.setValue(InvocationKey.INVOKER_PROXY_BINDING, null, PayloadKey.AS_IS);
inv.setType(InvocationType.LOCAL);
BeanMetaData bmd = container.getBeanMetaData();
SecurityIdentityMetaData ejbTimeoutIdentity = bmd.isEntity() ? null : bmd.getEjbTimeoutIdentity();
if( ejbTimeoutIdentity != null && ejbTimeoutIdentity.getUseCallerIdentity() == false )
{
ApplicationMetaData applicationMetaData = bmd.getApplicationMetaData();
AssemblyDescriptorMetaData assemblyDescriptor = applicationMetaData.getAssemblyDescriptor();
String roleName = ejbTimeoutIdentity.getRunAsRoleName();
String principalName = ejbTimeoutIdentity.getRunAsPrincipalName();
// the run-as principal might have extra roles mapped in the assembly-descriptor
Set extraRoleNames = assemblyDescriptor.getSecurityRoleNamesByPrincipal(principalName);
RunAs runAsIdentity = new RunAsIdentity(roleName, principalName, extraRoleNames);
SecurityActions.pushRunAsIdentity(runAsIdentity);
pushedRunAs = true;
}
container.invoke(inv);
}
finally
{
container.popENC();
if(pushedRunAs)
SecurityActions.popRunAsIdentity();
SecurityActions.setContextClassLoader(callerClassLoader);
}
}
// in src/main/java/org/jboss/ejb/txtimer/EJBTimerServiceImpl.java
protected void startService() throws Exception
{
// Setup plugins, fall back to safe defaults
// Get the TransactionManager from the factory, fall-back to the locator
if (transactionManagerFactory != null)
transactionManager = transactionManagerFactory.getTransactionManager();
else
transactionManager = TransactionManagerLocator.getInstance().locate();
// Get a proxy to the retry policy
try
{
retryPolicy = (RetryPolicy)MBeanProxyExt.create(RetryPolicy.class, getRetryPolicy(), server);
}
catch (Exception e)
{
log.error("Cannot obtain the implementation of a RetryPolicy", e);
}
// Get a proxy to the persistence policy
try
{
persistencePolicy = (PersistencePolicy)MBeanProxyExt.create(PersistencePolicy.class, persistencePolicyName, server);
}
catch (Exception e)
{
log.warn("Cannot obtain the implementation of a PersistencePolicy, using NoopPersistencePolicy: " + e.toString());
persistencePolicy = new NoopPersistencePolicy();
}
// Get the timerId generator
try
{
Class<?> timerIdGeneratorClass = getClass().getClassLoader().loadClass(timerIdGeneratorClassName);
timerIdGenerator = (TimerIdGenerator)timerIdGeneratorClass.newInstance();
}
catch (Exception e)
{
log.warn("Cannot obtain the implementation of a TimerIdGenerator, using BigIntegerTimerIdGenerator: " + e.toString());
timerIdGenerator = new BigIntegerTimerIdGenerator();
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void createService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Acquire classes from CL
if (metaData.getHome() != null)
homeInterface = classLoader.loadClass(metaData.getHome());
if (metaData.getRemote() != null)
remoteInterface = classLoader.loadClass(metaData.getRemote());
if (((SessionMetaData) metaData).getServiceEndpoint() != null)
{
serviceEndpoint =
classLoader.loadClass(((SessionMetaData) metaData).getServiceEndpoint());
}
// Call default init
super.createService();
// Make some additional validity checks with regards to the container configuration
checkCoherency();
// Map the bean methods
setupBeanMapping();
// Map the home methods
setupHomeMapping();
// Map the interfaces to Long
setupMarshalledInvocationMapping();
createInvokers();
createInstanceCache();
createInstancePool();
createPersistenceManager();
createInterceptors();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void setupMarshalledInvocationMapping() throws Exception
{
// Create method mappings for container invoker
if (homeInterface != null)
{
Method[] m = homeInterface.getMethods();
for (int i = 0; i < m.length; i++)
{
marshalledInvocationMapping.put(new Long(MarshalledInvocation.calculateHash(m[i])), m[i]);
}
}
if (remoteInterface != null)
{
Method[] m = remoteInterface.getMethods();
for (int j = 0; j < m.length; j++)
{
marshalledInvocationMapping.put(new Long(MarshalledInvocation.calculateHash(m[j])), m[j]);
}
}
// Get the getEJBObjectMethod
Method getEJBObjectMethod =
Class.forName("javax.ejb.Handle").getMethod("getEJBObject",
new Class[0]);
// Hash it
marshalledInvocationMapping.put(new Long(MarshalledInvocation.calculateHash(getEJBObjectMethod)), getEJBObjectMethod);
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void checkCoherency() throws Exception
{
// Check clustering cohrency wrt metadata
//
if (metaData.isClustered())
{
boolean clusteredProxyFactoryFound = false;
Iterator it = proxyFactories.keySet().iterator();
while (it.hasNext())
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
if (ci instanceof org.jboss.proxy.ejb.ClusterProxyFactory)
clusteredProxyFactoryFound = true;
}
if (!clusteredProxyFactoryFound)
{
log.warn("*** EJB '"
+ this.metaData.getEjbName()
+ "' deployed as CLUSTERED but not a single clustered-invoker is bound to container ***");
}
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void createInstancePool() throws Exception
{
// Try to register the instance pool as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "pool");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instancePool, poolName);
}
catch (Throwable t)
{
log.debug("Failed to register pool as mbean", t);
}
// Initialize pool
instancePool.setContainer(this);
instancePool.create();
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void createInstanceCache() throws Exception
{
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void createInvokers() throws Exception
{
// Init container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext();)
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
ci.create();
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void createInterceptors() throws Exception
{
Interceptor in = interceptor;
while (in != null)
{
in.setContainer(this);
in.create();
in = in.getNext();
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void createPersistenceManager() throws Exception
{
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void startService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Call default start
super.startService();
startInvokers();
startInstanceCache();
startInstancePool();
startPersistenceManager();
startInterceptors();
// Restore persisted ejb timers
restoreTimers();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void startPersistenceManager() throws Exception
{
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void startInstanceCache() throws Exception
{
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void startInvokers() throws Exception
{
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext();)
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
ci.start();
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void startInstancePool() throws Exception
{
instancePool.start();
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void startInterceptors() throws Exception
{
Interceptor in = interceptor;
while (in != null)
{
in.start();
in = in.getNext();
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void stopService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Call default stop
super.stopService();
stopInvokers();
stopInstanceCache();
stopInstancePool();
stopPersistenceManager();
stopInterceptors();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
protected void destroyService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
destroyInvokers();
destroyInstanceCache();
destroyInstancePool();
destroyPersistenceManager();
destroyInterceptors();
destroyMarshalledInvocationMapping();
homeInterface = null;
remoteInterface = null;
serviceEndpoint = null;
beanMapping.clear();
// Call default destroy
super.destroyService();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
public Object internalInvokeHome(Invocation mi) throws Exception
{
Method method = mi.getMethod();
if (method != null && method.getName().equals("remove"))
{
// Handle or primary key?
Object arg = mi.getArguments()[0];
if (arg instanceof Handle)
{
if (arg == null)
throw new RemoteException("Null handle");
Handle handle = (Handle) arg;
EJBObject ejbObject = handle.getEJBObject();
ejbObject.remove();
return null;
}
else
throw new RemoveException("EJBHome.remove(Object) not allowed for session beans");
}
// Invoke through interceptors
return getInterceptor().invokeHome(mi);
}
// in src/main/java/org/jboss/ejb/SessionContainer.java
public Object internalInvoke(Invocation mi) throws Exception
{
// Invoke through interceptors
return getInterceptor().invoke(mi);
}
// in src/main/java/org/jboss/ejb/StatelessSessionContainer.java
public Object invokeHome(Invocation mi) throws Exception
{
Method miMethod = mi.getMethod();
Method m = (Method) getHomeMapping().get(miMethod);
if (m == null)
{
String msg = "Invalid invocation, check your deployment packaging, method=" + miMethod;
throw new EJBException(msg);
}
try
{
return mi.performCall(StatelessSessionContainer.this, m, mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/ejb/StatelessSessionContainer.java
public Object invoke(Invocation mi) throws Exception
{
// wire the transaction on the context, this is how the instance remember the tx
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
if (ctx.getTransaction() == null)
ctx.setTransaction(mi.getTransaction());
// Get method and instance to invoke upon
Method miMethod = mi.getMethod();
Map map = getBeanMapping();
Method m = (Method) map.get(miMethod);
// The Invocation might contain the actual bean method
// e.g. For an invocation based on a JSR-181 @WebMethod annotation
if (m == null && map.values().contains(miMethod))
{
m = miMethod;
}
if (m == null)
{
String msg = "Invalid invocation, check your deployment packaging, method=" + miMethod;
throw new EJBException(msg);
}
//If we have a method that needs to be done by the container (EJBObject methods)
if (m.getDeclaringClass().equals(StatelessSessionContainer.class) ||
m.getDeclaringClass().equals(SessionContainer.class))
{
try
{
return mi.performCall(StatelessSessionContainer.this, m, new Object[]{mi});
}
catch (Exception e)
{
rethrow(e);
}
}
else // we have a method that needs to be done by a bean instance
{
// Invoke and handle exceptions
try
{
Object bean = ctx.getInstance();
return mi.performCall(bean, m, mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/ejb/SecurityActions.java
public Object run() throws Exception
{
Object proxy = MBeanProxy.get(iface, name, server);
Class[] ifaces = {iface};
InvocationHandler secureHandler = new InvocationHandlerAction(proxy);
Object secureProxy = Proxy.newProxyInstance(iface.getClassLoader(), ifaces, secureHandler);
return secureProxy;
}
// in src/main/java/org/jboss/ejb/SecurityActions.java
public Object run() throws Exception
{
Object value = method.invoke(mbean, args);
return value;
}
// in src/main/java/org/jboss/ejb/SecurityActions.java
static Object getMBeanProxy(Class iface, ObjectName name, MBeanServer server)
throws Exception
{
Object proxy;
if( System.getSecurityManager() == null )
{
proxy = MBeanProxy.get(iface, name, server);
}
else
{
MBeanProxyAction action = new MBeanProxyAction(iface, name, server);
proxy = AccessController.doPrivileged(action);
}
return proxy;
}
// in src/main/java/org/jboss/ejb/SecurityActions.java
public Object run() throws Exception
{
return (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
}
// in src/main/java/org/jboss/ejb/SecurityActions.java
static boolean isCallerInRole(final SecurityContext sc, final String roleName,
final String ejbName, final Principal principal, final Subject contextSubject,
final String jaccContextID, final Set<SecurityRoleRef> securityRoleRefs)
throws PrivilegedActionException
{
return AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>()
{
public Boolean run() throws Exception
{
AbstractEJBAuthorizationHelper helper = SecurityHelperFactory.getEJBAuthorizationHelper(sc);
return helper.isCallerInRole(roleName,
ejbName, principal, contextSubject,
jaccContextID, securityRoleRefs);
}
});
}
// in src/main/java/org/jboss/ejb/SecurityActions.java
public Boolean run() throws Exception
{
AbstractEJBAuthorizationHelper helper = SecurityHelperFactory.getEJBAuthorizationHelper(sc);
return helper.isCallerInRole(roleName,
ejbName, principal, contextSubject,
jaccContextID, securityRoleRefs);
}
// in src/main/java/org/jboss/ejb/EjbModule.java
Override
protected void createService() throws Exception
{
serviceController = (ServiceControllerMBean) MBeanProxyExt.create(ServiceControllerMBean.class,
ServiceControllerMBean.OBJECT_NAME, server);
log.debug("createService, begin");
// Set up the beans in this module.
try
{
Iterator beans = appMetaData.getEnterpriseBeans();
String contextID = appMetaData.getJaccContextID();
if (contextID == null)
contextID = deploymentUnit.getSimpleName();
// appMetaData.gsetJaccContextID(contextID);
/* PolicyConfiguration pc = null; */
while (beans.hasNext())
{
BeanMetaData bean = (BeanMetaData) beans.next();
log.info("Deploying " + bean.getEjbName());
Container con = createContainer(bean, deploymentUnit);
addContainer(con);
// @todo support overriding the context id via metadata is needed
con.setJaccContextID(contextID);
}
// only one iteration should be necessary, but we won't sweat it.
// 2 iterations are needed by cmp...jdbc/bridge/JDBCCMRFieldBridge which
// assumes persistence managers are all set up for every
// bean in the relationship!
ListIterator iter = containerOrdering.listIterator();
while (iter.hasNext())
{
Container con = (Container) iter.next();
ObjectName jmxName = con.getJmxName();
/*
* Add the container mbean to the deployment mbeans so the state of the deployment can be tracked.
*/
server.registerMBean(con, jmxName);
// deploymentUnit.mbeans.add(jmxName);
BeanMetaData metaData = con.getBeanMetaData();
Collection<ObjectName> depends = new ArrayList<ObjectName>();
for (String dependsName : metaData.getDepends())
{
depends.add(ObjectName.getInstance(dependsName));
}
Iterator<String> invokerBindings = metaData.getInvokerBindings();
while (invokerBindings != null && invokerBindings.hasNext())
{
String invokerBindingName = invokerBindings.next();
InvokerProxyBindingMetaData ipbmd = appMetaData.getInvokerProxyBindingMetaDataByName(invokerBindingName);
if (ipbmd != null)
{
String invokerName = ipbmd.getInvokerMBean();
if (invokerName != null)
{
try
{
ObjectName invokerMBean = ObjectName.getInstance(invokerName);
if (depends.contains(invokerMBean) == false)
depends.add(invokerMBean);
}
catch (MalformedObjectNameException e)
{
log.trace("Ignored malformed invoker mbean '" + invokerName + "' " + e.toString());
}
}
}
}
serviceController.create(jmxName, depends);
// We keep the hashCode around for fast creation of proxies
int jmxHash = jmxName.hashCode();
Registry.bind(new Integer(jmxHash), jmxName);
log.debug("Bound jmxName=" + jmxName + ", hash=" + jmxHash + "into Registry");
}
}
catch (Exception e)
{
destroyService();
throw e;
} // end of try-catch
}
// in src/main/java/org/jboss/ejb/EjbModule.java
Override
protected void startService() throws Exception
{
// before EntityContainer returns from the startService, its PM should be usable
ListIterator iter = containerOrdering.listIterator();
while (iter.hasNext())
{
Container con = (Container) iter.next();
if (con.getBeanMetaData().isEntity())
{
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(con.getClassLoader());
con.pushENC();
try
{
((EntityContainer) con).getPersistenceManager().start();
}
finally
{
con.popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
}
iter = containerOrdering.listIterator();
while (iter.hasNext())
{
Container con = (Container) iter.next();
log.debug("startService, starting container: " + con.getBeanMetaData().getEjbName());
serviceController.start(con.getJmxName());
}
}
// in src/main/java/org/jboss/ejb/EjbModule.java
Override
protected void stopService() throws Exception
{
ListIterator iter = containerOrdering.listIterator(containerOrdering.size());
while (iter.hasPrevious())
{
Container con = (Container) iter.previous();
try
{
ObjectName jmxName = con.getJmxName();
// The container may already be destroyed so validate metaData
BeanMetaData metaData = con.getBeanMetaData();
String ejbName = metaData != null ? metaData.getEjbName() : "Unknown";
log.debug("stopService, stopping container: " + ejbName);
serviceController.stop(jmxName);
}
catch (Exception e)
{
log.error("unexpected exception stopping Container: " + con.getJmxName(), e);
} // end of try-catch
}
}
// in src/main/java/org/jboss/ejb/EjbModule.java
Override
protected void destroyService() throws Exception
{
WebServiceMBean webServer = null;
if (webServiceName != null)
{
webServer = (WebServiceMBean) MBeanProxyExt.create(WebServiceMBean.class, webServiceName);
}
ListIterator iter = containerOrdering.listIterator(containerOrdering.size());
while (iter.hasPrevious())
{
Container con = (Container) iter.previous();
ObjectName jmxName = con.getJmxName();
int conState = con.getState();
boolean destroyContainer = true;
log.debug("Looking to destroy container: " + jmxName + ", state: " + con.getStateString() + ", destroy: "
+ destroyContainer);
// always unregister from Registry
int jmxHash = jmxName.hashCode();
Registry.unbind(new Integer(jmxHash));
// Unregister the web classloader
// Removing the wcl should probably be done in stop of the container,
// but I don't want to look for errors today.
if (webServer != null)
{
ClassLoader wcl = con.getWebClassLoader();
if (wcl != null)
{
try
{
webServer.removeClassLoader(wcl);
}
catch (Throwable e)
{
log.warn("Failed to unregister webClassLoader", e);
}
}
}
// Only destroy containers that have been created or started
if (destroyContainer)
{
try
{
serviceController.destroy(jmxName);
serviceController.remove(jmxName);
log.info("Undeployed " + con.getBeanMetaData().getEjbName());
if (server.isRegistered(jmxName))
server.unregisterMBean(jmxName);
}
catch (Throwable e)
{
log.error("unexpected exception destroying Container: " + jmxName, e);
} // end of try-catch
}
// Destroy proxy factories
if (destroyContainer)
{
if (con.getBeanMetaData() != null && con.getBeanMetaData().getInvokerBindings() != null)
{
Iterator<String> invokerBindings = con.getBeanMetaData().getInvokerBindings();
while (invokerBindings.hasNext())
{
String invoker = invokerBindings.next();
EJBProxyFactory ci = con.lookupProxyFactory(invoker);
if (ci != null)
{
ci.setContainer(null);
ci.setInvokerBinding(null);
ci.setInvokerMetaData(null);
}
}
}
}
// cleanup container
con.setBeanMetaData(null);
con.setWebClassLoader(null);
con.setClassLoader(null);
con.setEjbModule(null);
con.setTransactionManager(null);
con.setSecurityManager(null);
con.setRealmMapping(null);
con.setSecurityProxy(null);
con.setSecurityManagement(null);
con.setPolicyRegistration(null);
con.proxyFactories.clear();
}
this.containers.clear();
this.localHomes.clear();
this.containerOrdering.clear();
this.moduleData.clear();
this.serviceController = null;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private Container createContainer(BeanMetaData bean, VFSDeploymentUnit unit) throws Exception
{
Container container = null;
// Added message driven deployment
if (bean.isMessageDriven())
{
container = createMessageDrivenContainer(bean, unit);
}
else if (bean.isSession()) // Is session?
{
if (((SessionMetaData) bean).isStateless()) // Is stateless?
{
container = createStatelessSessionContainer((SessionMetaData) bean, unit);
}
else
// Stateful
{
container = createStatefulSessionContainer((SessionMetaData) bean, unit);
}
}
else
// Entity
{
container = createEntityContainer(bean, unit);
}
container.setDeploymentUnit(unit);
return container;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private MessageDrivenContainer createMessageDrivenContainer(BeanMetaData bean, DeploymentUnit unit) throws Exception
{
// get the container configuration for this bean
// a default configuration is now always provided
ConfigurationMetaData conf = bean.getContainerConfiguration();
// Stolen from Stateless deploy
// Create container
MessageDrivenContainer container = new MessageDrivenContainer();
int transType = bean.isContainerManagedTx() ? CMT : BMT;
initializeContainer(container, conf, bean, transType, unit);
createProxyFactories(bean, container);
container.setInstancePool(createInstancePool(conf, unit.getClassLoader()));
return container;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private StatelessSessionContainer createStatelessSessionContainer(SessionMetaData bean, DeploymentUnit unit)
throws Exception
{
// get the container configuration for this bean
// a default configuration is now always provided
ConfigurationMetaData conf = bean.getContainerConfiguration();
// Create container
StatelessSessionContainer container = new StatelessSessionContainer();
int transType = bean.isContainerManagedTx() ? CMT : BMT;
initializeContainer(container, conf, bean, transType, unit);
if (bean.getHome() != null || bean.getServiceEndpoint() != null)
{
createProxyFactories(bean, container);
}
container.setInstancePool(createInstancePool(conf, unit.getClassLoader()));
return container;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private StatefulSessionContainer createStatefulSessionContainer(SessionMetaData bean, DeploymentUnit unit)
throws Exception
{
// get the container configuration for this bean
// a default configuration is now always provided
ConfigurationMetaData conf = bean.getContainerConfiguration();
// Create container
StatefulSessionContainer container = new StatefulSessionContainer();
int transType = bean.isContainerManagedTx() ? CMT : BMT;
initializeContainer(container, conf, bean, transType, unit);
if (bean.getHome() != null || bean.getServiceEndpoint() != null)
{
createProxyFactories(bean, container);
}
ClassLoader cl = unit.getClassLoader();
container.setInstanceCache(createInstanceCache(conf, cl));
// No real instance pool, use the shadow class
StatefulSessionInstancePool ip = new StatefulSessionInstancePool();
ip.importXml(conf.getContainerPoolConf());
container.setInstancePool(ip);
// Set persistence manager
container.setPersistenceManager((StatefulSessionPersistenceManager) cl.loadClass(conf.getPersistenceManager())
.newInstance());
// Set the bean Lock Manager
container.setLockManager(createBeanLockManager(container, false, conf.getLockClass(), cl));
return container;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private EntityContainer createEntityContainer(BeanMetaData bean, DeploymentUnit unit) throws Exception
{
// get the container configuration for this bean
// a default configuration is now always provided
ConfigurationMetaData conf = bean.getContainerConfiguration();
// Create container
EntityContainer container = new EntityContainer();
int transType = CMT;
initializeContainer(container, conf, bean, transType, unit);
if (bean.getHome() != null)
{
createProxyFactories(bean, container);
}
ClassLoader cl = unit.getClassLoader();
container.setInstanceCache(createInstanceCache(conf, cl));
container.setInstancePool(createInstancePool(conf, cl));
// Set the bean Lock Manager
boolean reentrant = ((EntityMetaData) bean).isReentrant();
BeanLockManager lockMgr = createBeanLockManager(container, reentrant, conf.getLockClass(), cl);
container.setLockManager(lockMgr);
// Set persistence manager
if (((EntityMetaData) bean).isBMP())
{
Class pmClass = cl.loadClass(conf.getPersistenceManager());
EntityPersistenceManager pm = (EntityPersistenceManager) pmClass.newInstance();
container.setPersistenceManager(pm);
}
else
{
// CMP takes a manager and a store
org.jboss.ejb.plugins.CMPPersistenceManager persistenceManager = new org.jboss.ejb.plugins.CMPPersistenceManager();
// Load the store from configuration
Class pmClass = cl.loadClass(conf.getPersistenceManager());
EntityPersistenceStore pm = (EntityPersistenceStore) pmClass.newInstance();
persistenceManager.setPersistenceStore(pm);
// Set the manager on the container
container.setPersistenceManager(persistenceManager);
}
return container;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private static void createProxyFactories(BeanMetaData conf, Container container) throws Exception
{
ClassLoader cl = container.getClassLoader();
Iterator it = conf.getInvokerBindings();
boolean foundOne = false;
while (it.hasNext())
{
String invoker = (String) it.next();
String jndiBinding = conf.getInvokerBinding(invoker);
log.debug("creating binding for " + jndiBinding + ":" + invoker);
InvokerProxyBindingMetaData imd = conf.getApplicationMetaData().getInvokerProxyBindingMetaDataByName(invoker);
EJBProxyFactory ci = null;
// create a ProxyFactory instance
try
{
ci = (EJBProxyFactory) cl.loadClass(imd.getProxyFactory()).newInstance();
ci.setContainer(container);
ci.setInvokerMetaData(imd);
ci.setInvokerBinding(jndiBinding);
if (ci instanceof XmlLoadable)
{
// the container invoker can load its configuration from the jboss.xml element
((XmlLoadable) ci).importXml(imd.getProxyFactoryConfig());
}
container.addProxyFactory(invoker, ci);
foundOne = true;
}
catch (Exception e)
{
log.warn("The Container Invoker " + invoker
+ " (in jboss.xml or standardjboss.xml) could not be created because of " + e
+ " We will ignore this error, but you may miss a transport for this bean.");
}
}
if (!foundOne)
{
throw new DeploymentException("Missing or invalid Container Invokers (in jboss.xml or standardjboss.xml).");
}
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private static BeanLockManager createBeanLockManager(Container container, boolean reentrant, String beanLock,
ClassLoader cl) throws Exception
{
// The bean lock manager
BeanLockManager lockManager = new BeanLockManager(container);
Class lockClass = null;
try
{
if (beanLock == null)
beanLock = "org.jboss.ejb.plugins.lock.QueuedPessimisticEJBLock";
lockClass = cl.loadClass(beanLock);
}
catch (Exception e)
{
throw new DeploymentException("Missing or invalid lock class (in jboss.xml or standardjboss.xml): " + beanLock
+ " - " + e);
}
lockManager.setLockCLass(lockClass);
lockManager.setReentrant(reentrant);
return lockManager;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private static InstancePool createInstancePool(ConfigurationMetaData conf, ClassLoader cl) throws Exception
{
// Set instance pool
InstancePool ip = null;
try
{
ip = (InstancePool) cl.loadClass(conf.getInstancePool()).newInstance();
}
catch (Exception e)
{
throw new DeploymentException("Missing or invalid Instance Pool (in jboss.xml or standardjboss.xml)", e);
}
if (ip instanceof XmlLoadable)
((XmlLoadable) ip).importXml(conf.getContainerPoolConf());
return ip;
}
// in src/main/java/org/jboss/ejb/EjbModule.java
private static InstanceCache createInstanceCache(ConfigurationMetaData conf, ClassLoader cl) throws Exception
{
// Set instance cache
InstanceCache ic = null;
try
{
ic = (InstanceCache) cl.loadClass(conf.getInstanceCache()).newInstance();
}
catch (Exception e)
{
throw new DeploymentException("Missing or invalid Instance Cache (in jboss.xml or standardjboss.xml)", e);
}
if (ic instanceof XmlLoadable)
((XmlLoadable) ic).importXml(conf.getContainerCacheConf());
return ic;
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
protected void createService() throws Exception
{
super.createService();
// Get the Handle.getEJBObject method for permission checks
try
{
getEJBObject = Handle.class.getMethod("getEJBObject", new Class[0]);
}
catch (Exception e)
{
log.warn("Failed to grant access to the Handle.getEJBObject method");
}
ejbObjectRemove = EJBObject.class.getMethod("remove", null);
ejbLocalObjectRemove = EJBLocalObject.class.getMethod("remove", null);
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
protected void createInstanceCache() throws Exception
{
// Try to register the instance cache as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "cache");
ObjectName cacheName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instanceCache, cacheName);
}
catch (Throwable t)
{
log.debug("Failed to register cache as mbean", t);
}
// Init instance cache
instanceCache.setContainer(this);
instanceCache.create();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
protected void createPersistenceManager() throws Exception
{
persistenceManager.setContainer(this);
persistenceManager.create();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
protected void startPersistenceManager() throws Exception
{
persistenceManager.start();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
protected void startInstanceCache() throws Exception
{
instanceCache.start();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
private void createSession(final Method m,
final Object[] args,
final StatefulSessionEnterpriseContext ctx)
throws Exception
{
// Create a new ID and set it
Object id = getPersistenceManager().createId(ctx);
log.debug("Created new session ID: " + id);
ctx.setId(id);
// Invoke ejbCreate<METHOD>()
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_CREATE);
// Build the ejbCreate<METHOD> from the home create<METHOD> sig
String createName = m.getName();
Object instance = ctx.getInstance();
String ejbCreateName = "ejbC" + createName.substring(1);
Method createMethod = instance.getClass().getMethod(ejbCreateName, m.getParameterTypes());
log.debug("Using create method for session: " + createMethod);
createMethod.invoke(instance, args);
createCount++;
}
catch (IllegalAccessException e)
{
ctx.setId(null);
throw new EJBException(e);
}
catch (InvocationTargetException e)
{
ctx.setId(null);
Throwable t = e.getTargetException();
if (t instanceof RuntimeException)
{
if (t instanceof EJBException)
throw (EJBException) t;
// Wrap runtime exceptions
throw new EJBException((Exception) t);
}
else if (t instanceof Exception)
{
// Remote, Create, or custom app. exception
throw (Exception) t;
}
else if (t instanceof Error)
{
throw (Error) t;
}
else
{
throw new org.jboss.util.UnexpectedThrowable(t);
}
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
// call back to the PM to let it know that ejbCreate has been called with success
getPersistenceManager().createdSession(ctx);
// Insert in cache
getInstanceCache().insert(ctx);
// Create EJBObject
if (getProxyFactory() != null)
ctx.setEJBObject((EJBObject) getProxyFactory().getStatefulSessionEJBObject(id));
// Create EJBLocalObject
if (getLocalHomeClass() != null)
ctx.setEJBLocalObject(getLocalProxyFactory().getStatefulSessionEJBLocalObject(id));
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
public EJBObject createHome(Invocation mi)
throws Exception
{
StatefulSessionEnterpriseContext ctx = (StatefulSessionEnterpriseContext) mi.getEnterpriseContext();
createSession(mi.getMethod(), mi.getArguments(), ctx);
return ctx.getEJBObject();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
public EJBLocalObject createLocalHome(Invocation mi)
throws Exception
{
StatefulSessionEnterpriseContext ctx = (StatefulSessionEnterpriseContext) mi.getEnterpriseContext();
createSession(mi.getMethod(), mi.getArguments(), ctx);
return ctx.getEJBLocalObject();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
protected void setupHomeMapping() throws Exception
{
// Adrian Brock: This should go away when we don't support EJB1x
boolean isEJB1x = metaData.getApplicationMetaData().isEJB1x();
Map map = new HashMap();
if (homeInterface != null)
{
Method[] m = homeInterface.getMethods();
for (int i = 0; i < m.length; i++)
{
try
{
// Implemented by container
if (isEJB1x == false && m[i].getName().startsWith("create"))
{
map.put(m[i], getClass().getMethod("createHome",
new Class[]{Invocation.class}));
}
else
{
map.put(m[i], getClass().getMethod(m[i].getName() + "Home",
new Class[]{Invocation.class}));
}
}
catch (NoSuchMethodException e)
{
log.info(m[i].getName() + " in bean has not been mapped");
}
}
}
if (localHomeInterface != null)
{
Method[] m = localHomeInterface.getMethods();
for (int i = 0; i < m.length; i++)
{
try
{
// Implemented by container
if (isEJB1x == false && m[i].getName().startsWith("create"))
{
map.put(m[i], getClass().getMethod("createLocalHome",
new Class[]{Invocation.class}));
}
else
{
map.put(m[i], getClass().getMethod(m[i].getName() + "LocalHome",
new Class[]{Invocation.class}));
}
}
catch (NoSuchMethodException e)
{
log.info(m[i].getName() + " in bean has not been mapped");
}
}
}
try
{
// Get getEJBObject from on Handle, first get the class
Class handleClass = Class.forName("javax.ejb.Handle");
//Get only the one called handle.getEJBObject
Method getEJBObjectMethod = handleClass.getMethod("getEJBObject", new Class[0]);
//Map it in the home stuff
map.put(getEJBObjectMethod, getClass().getMethod("getEJBObject",
new Class[]{Invocation.class}));
}
catch (NoSuchMethodException e)
{
log.debug("Couldn't find getEJBObject method on container");
}
homeMapping = map;
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
public Object invokeHome(Invocation mi) throws Exception
{
boolean trace = log.isTraceEnabled();
if (trace)
{
log.trace("HOMEMETHOD coming in ");
log.trace("" + mi.getMethod());
log.trace("HOMEMETHOD coming in hashcode" + mi.getMethod().hashCode());
log.trace("HOMEMETHOD coming in classloader" + mi.getMethod().getDeclaringClass().getClassLoader().hashCode());
log.trace("CONTAINS " + getHomeMapping().containsKey(mi.getMethod()));
}
Method miMethod = mi.getMethod();
Method m = (Method) getHomeMapping().get(miMethod);
if (m == null)
{
String msg = "Invalid invocation, check your deployment packaging"
+ ", method=" + miMethod;
throw new EJBException(msg);
}
// Invoke and handle exceptions
if (trace)
{
log.trace("HOMEMETHOD m " + m);
java.util.Iterator iterator = getHomeMapping().keySet().iterator();
while (iterator.hasNext())
{
Method me = (Method) iterator.next();
if (me.getName().endsWith("create"))
{
log.trace(me.toString());
log.trace("" + me.hashCode());
log.trace("" + me.getDeclaringClass().getClassLoader().hashCode());
log.trace("equals " + me.equals(mi.getMethod()) + " " + mi.getMethod().equals(me));
}
}
}
try
{
return mi.performCall(StatefulSessionContainer.this, m, new Object[]{mi});
}
catch (Exception e)
{
rethrow(e);
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/ejb/StatefulSessionContainer.java
public Object invoke(Invocation mi) throws Exception
{
// Get method
Method miMethod = mi.getMethod();
Method m = (Method) getBeanMapping().get(miMethod);
if (m == null)
{
String msg = "Invalid invocation, check your deployment packaging"
+ ", method=" + miMethod;
throw new EJBException(msg);
}
// wire the transaction on the context, this is how the instance remember the tx
// Unlike Entity beans we can't do that in the previous interceptors (ordering)
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
if (ctx.getTransaction() == null)
ctx.setTransaction(mi.getTransaction());
else if(ejbObjectRemove.equals(miMethod) || ejbLocalObjectRemove.equals(miMethod))
{
throw new RemoveException("An attempt to remove a session " +
"object while the object is in a transaction " +
"(EJB2.1, 7.6.4 Restrictions for Transactions): ejb-name=" +
metaData.getEjbName() + ", method=" + mi.getMethod() + ", tx=" + ctx.getTransaction());
}
// Select instance to invoke (container or bean)
if (m.getDeclaringClass().equals(StatefulSessionContainer.class)
|| m.getDeclaringClass().equals(SessionContainer.class))
{
// Invoke and handle exceptions
try
{
return mi.performCall(StatefulSessionContainer.this, m, new Object[]{mi});
}
catch (Exception e)
{
rethrow(e);
}
}
else
{
// Invoke and handle exceptions
try
{
Object bean = ctx.getInstance();
return mi.performCall(bean, m, mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/ejb/Container.java
public Object createBeanClassInstance() throws Exception
{
return getBeanClass().newInstance();
}
// in src/main/java/org/jboss/ejb/Container.java
protected void createService() throws Exception
{
// Acquire classes from CL
beanClass = classLoader.loadClass(metaData.getEjbClass());
if (metaData.getLocalHome() != null)
localHomeInterface = classLoader.loadClass(metaData.getLocalHome());
if (metaData.getLocal() != null)
localInterface = classLoader.loadClass(metaData.getLocal());
localProxyFactory.setContainer(this);
localProxyFactory.create();
if (localHomeInterface != null)
ejbModule.addLocalHome(this, localProxyFactory.getEJBLocalHome());
ejbModule.createMissingPermissions(this, metaData);
// Allow the policy to incorporate the policy configs
Policy.getPolicy().refresh();
}
// in src/main/java/org/jboss/ejb/Container.java
protected void startService() throws Exception
{
// Setup "java:comp/env" namespace
setupEnvironment();
localProxyFactory.start();
}
// in src/main/java/org/jboss/ejb/Container.java
protected void stopService() throws Exception
{
localProxyFactory.stop();
removeTimerService(null);
teardownEnvironment();
}
// in src/main/java/org/jboss/ejb/Container.java
protected void destroyService() throws Exception
{
cleanENC();
localProxyFactory.destroy();
ejbModule.removeLocalHome(this);
beanClass = null;
homeInterface = null;
remoteInterface = null;
localHomeInterface = null;
localInterface = null;
methodPermissionsCache.clear();
// InvocationStatistics holds refs to Methods from
// application classes, so to avoid a classloader
// leak, lets not just resetStats() but also replace
// the object
invokeStats.resetStats(); // in case someone else has a ref
invokeStats = new InvocationStatistics();
marshalledInvocationMapping.clear();
}
// in src/main/java/org/jboss/ejb/Container.java
public Object invoke(Invocation mi) throws Exception
{
ClassLoader callerClassLoader = SecurityActions.getContextClassLoader();
long start = System.currentTimeMillis();
Method m = null;
Object type = null;
String contextID = getJaccContextID();
try
{
pushENC();
// JBAS-3732 - Remove classloader.equals optimization
SecurityActions.setContextClassLoader(this.classLoader);
// Set the JACC context id
mi.setValue(InvocationKey.JACC_CONTEXT_ID, contextID);
contextID = SecurityActions.setContextID(contextID);
// Set the standard JACC policy context handler data is not a SEI msg
if (mi.getType() != InvocationType.SERVICE_ENDPOINT)
{
EJBArgsPolicyContextHandler.setArgs(mi.getArguments());
}
else
{
SOAPMessage msg = (SOAPMessage)mi.getValue(InvocationKey.SOAP_MESSAGE);
SOAPMsgPolicyContextHandler.setMessage(msg);
}
// Set custom JACC policy handlers
BeanMetaDataPolicyContextHandler.setMetaData(this.getBeanMetaData());
// Check against home, remote, localHome, local, getHome,
// getRemote, getLocalHome, getLocal
type = mi.getType();
// stat gathering: concurrent calls
this.invokeStats.callIn();
if (type == InvocationType.REMOTE || type == InvocationType.LOCAL ||
// web service calls come in as "ordinary" application invocations
type == InvocationType.SERVICE_ENDPOINT)
{
if (mi instanceof MarshalledInvocation)
{
((MarshalledInvocation)mi).setMethodMap(marshalledInvocationMapping);
if (log.isTraceEnabled())
{
log.trace("METHOD REMOTE INVOKE " + mi.getObjectName() + "||" + mi.getMethod().getName() + "||");
}
}
m = mi.getMethod();
Object obj = internalInvoke(mi);
return obj;
}
else if (type == InvocationType.HOME || type == InvocationType.LOCALHOME)
{
if (mi instanceof MarshalledInvocation)
{
((MarshalledInvocation)mi).setMethodMap(marshalledInvocationMapping);
if (log.isTraceEnabled())
{
log.trace("METHOD HOME INVOKE " + mi.getObjectName() + "||" + mi.getMethod().getName() + "||" + mi.getArguments().toString());
}
}
m = mi.getMethod();
Object obj = internalInvokeHome(mi);
return obj;
}
else
{
throw new MBeanException(new IllegalArgumentException("Unknown invocation type: " + type));
}
}
/**
* Having to catch this exception here in case can not
* unmarshall arguments, values, etc. Then, convert to
* UnmarshalException as defined by spec (JBAS-2999)
*/
catch (JBossLazyUnmarshallingException e)
{
InvocationType calltype = mi.getType();
boolean isLocal = calltype == InvocationType.LOCAL || calltype == InvocationType.LOCALHOME;
// handle unmarshalling exception which should only come if problem unmarshalling
// invocation payload, arguments, or value on remote end.
if (isLocal)
{
throw new EJBException("UnmarshalException", e);
}
else
{
throw new MarshalException("MarshalException", e);
}
}
finally
{
if (m != null)
{
long end = System.currentTimeMillis();
long elapsed = end - start;
this.invokeStats.updateStats(m, elapsed);
}
// stat gathering: concurrent calls
this.invokeStats.callOut();
popENC();
// Restore the incoming class loader
SecurityActions.setContextClassLoader(callerClassLoader);
// Restore the incoming context id
contextID = SecurityActions.setContextID(contextID);
if (mi.getType() == InvocationType.SERVICE_ENDPOINT)
{
// Remove msg from ThreadLocal to prevent leakage into the thread pool
SOAPMsgPolicyContextHandler.setMessage(null);
}
else
{
// Remove args from ThreadLocal to prevent leakage into the thread pool
EJBArgsPolicyContextHandler.setArgs(null);
}
// Remove metadata from ThreadLocal to prevent leakage into the thread pool
BeanMetaDataPolicyContextHandler.setMetaData(null);
}
}
// in src/main/java/org/jboss/ejb/Container.java
private void setupEnvironment() throws Exception
{
BeanMetaData beanMetaData = getBeanMetaData();
// debug
log.debug("Begin java:comp/env for EJB: " + beanMetaData.getEjbName());
ClassLoader tcl = SecurityActions.getContextClassLoader();
log.debug("TCL: " + tcl);
ORB orb = null;
HandleDelegate hd = null;
try
{
orb = (ORB)server.getAttribute(ORB_NAME, "ORB");
hd = (HandleDelegate)server.getAttribute(ORB_NAME, "HandleDelegate");
}
catch (Throwable t)
{
log.debug("Unable to retrieve orb" + t.toString());
}
// Since the BCL is already associated with this thread we can start
// using the java: namespace directly
Context ctx = (Context)new InitialContext().lookup("java:comp");
Object id = ENCFactory.getCurrentId();
log.debug("Using java:comp using id=" + id);
// Bind the orb
if (orb != null)
{
NonSerializableFactory.rebind(ctx, "ORB", orb);
log.debug("Bound java:comp/ORB for EJB: " + getBeanMetaData().getEjbName());
NonSerializableFactory.rebind(ctx, "HandleDelegate", hd);
log.debug("Bound java:comp/HandleDelegate for EJB: " + getBeanMetaData().getEjbName());
}
// JTA links
ctx.bind("TransactionSynchronizationRegistry", new LinkRef("java:TransactionSynchronizationRegistry"));
log.debug("Linked java:comp/TransactionSynchronizationRegistry to JNDI name: java:TransactionSynchronizationRegistry");
Context envCtx = ctx.createSubcontext("env");
// Bind environment properties
{
Iterator i = beanMetaData.getEnvironmentEntries();
while (i.hasNext())
{
EnvEntryMetaData entry = (EnvEntryMetaData)i.next();
log.debug("Binding env-entry: " + entry.getName() + " of type: " + entry.getType() + " to value:" + entry.getValue());
EnvEntryBinder.bindEnvEntry(envCtx, entry);
}
}
// Bind EJB references
{
Iterator i = beanMetaData.getEjbReferences();
while (i.hasNext())
{
EjbRefMetaData ref = (EjbRefMetaData)i.next();
log.debug("Binding an EJBReference " + ref.getName());
if (ref.getLink() != null)
{
// Internal link
String linkName = ref.getLink();
String jndiName = ref.getJndiName();
log.debug("Binding " + ref.getName() + " to ejb-link: " + linkName + " -> " + jndiName);
if (jndiName == null)
{
String msg = "Failed to resolve ejb-link: " + linkName + " from ejb-ref: " + ref.getName() + " in ejb: " + beanMetaData.getEjbName();
throw new DeploymentException(msg);
}
Util.bind(envCtx, ref.getName(), new LinkRef(jndiName));
}
else
{
// Get the invoker specific ejb-ref mappings
Iterator it = beanMetaData.getInvokerBindings();
Reference reference = null;
while (it.hasNext())
{
String invokerBinding = (String)it.next();
// Check for an invoker level jndi-name
String name = ref.getInvokerBinding(invokerBinding);
// Check for an global jndi-name
if (name == null)
name = ref.getJndiName();
if (name == null)
{
throw new DeploymentException("ejb-ref " + ref.getName() + ", expected either ejb-link in ejb-jar.xml or " + "jndi-name in jboss.xml");
}
StringRefAddr addr = new StringRefAddr(invokerBinding, name);
log.debug("adding " + invokerBinding + ":" + name + " to Reference");
if (reference == null)
{
reference = new Reference("javax.naming.LinkRef", ENCThreadLocalKey.class.getName(), null);
}
reference.add(addr);
}
// If there were invoker bindings create bind the reference
if (reference != null)
{
if (ref.getJndiName() != null)
{
// Add default for the bean level ejb-ref/jndi-name
StringRefAddr addr = new StringRefAddr("default", ref.getJndiName());
reference.add(addr);
}
if (reference.size() == 1 && reference.get("default") == null)
{
/* There is only one invoker binding and its not default so
create a default binding to allow the link to have a value
when accessed without an invoker active.
*/
StringRefAddr addr = (StringRefAddr)reference.get(0);
String target = (String)addr.getContent();
StringRefAddr addr1 = new StringRefAddr("default", target);
reference.add(addr1);
}
Util.bind(envCtx, ref.getName(), reference);
}
else
{
// Bind the bean level ejb-ref/jndi-name
if (ref.getJndiName() == null)
{
throw new DeploymentException("ejb-ref " + ref.getName() + ", expected either ejb-link in ejb-jar.xml " + "or jndi-name in jboss.xml");
}
Util.bind(envCtx, ref.getName(), new LinkRef(ref.getJndiName()));
}
}
}
}
// Bind Local EJB references
{
Iterator i = beanMetaData.getEjbLocalReferences();
while (i.hasNext())
{
EjbLocalRefMetaData ref = (EjbLocalRefMetaData)i.next();
String refName = ref.getName();
log.debug("Binding an EJBLocalReference " + ref.getName());
if (ref.getLink() != null)
{
// Internal link
log.debug("Binding " + refName + " to bean source: " + ref.getLink());
String jndiName = ref.getJndiName();
Util.bind(envCtx, ref.getName(), new LinkRef(jndiName));
}
else
{
// Bind the bean level ejb-local-ref/local-jndi-name
if (ref.getJndiName() == null)
{
throw new DeploymentException("ejb-local-ref " + ref.getName() + ", expected either ejb-link in ejb-jar.xml " + "or local-jndi-name in jboss.xml");
}
Util.bind(envCtx, ref.getName(), new LinkRef(ref.getJndiName()));
}
}
}
// Bind service references
{
ClassLoader loader = unit.getClassLoader();
UnifiedVirtualFile vfsRoot = new VirtualFileAdaptor(unit.getRoot());
Iterator<ServiceReferenceMetaData> serviceReferences = beanMetaData.getServiceReferences();
if (serviceReferences != null)
{
while (serviceReferences.hasNext())
{
ServiceReferenceMetaData sref = serviceReferences.next();
String refName = sref.getServiceRefName();
new ServiceReferenceHandler().bindServiceRef(envCtx, refName, vfsRoot, loader, sref);
}
}
}
// Bind resource references
{
Iterator i = beanMetaData.getResourceReferences();
// let's play guess the cast game ;) New metadata should fix this.
ApplicationMetaData application = beanMetaData.getApplicationMetaData();
while (i.hasNext())
{
ResourceRefMetaData ref = (ResourceRefMetaData)i.next();
String resourceName = ref.getResourceName();
String finalName = application.getResourceByName(resourceName);
String resType = ref.getType();
// If there was no resource-manager specified then an immeadiate
// jndi-name or res-url name should have been given
if (finalName == null)
finalName = ref.getJndiName();
if (finalName == null && resType.equals("java.net.URL") == false)
{
// the application assembler did not provide a resource manager
// if the type is javax.sql.Datasoure use the default one
if (ref.getType().equals("javax.sql.DataSource"))
{
// Go through JNDI and look for DataSource - use the first one
Context dsCtx = new InitialContext();
try
{
// Check if it is available in JNDI
dsCtx.lookup("java:/DefaultDS");
finalName = "java:/DefaultDS";
}
catch (Exception e)
{
log.debug("failed to lookup DefaultDS; ignoring", e);
}
finally
{
dsCtx.close();
}
}
// Default failed? Warn user and move on
// POTENTIALLY DANGEROUS: should this be a critical error?
if (finalName == null)
{
log.warn("No resource manager found for " + ref.getResourceName());
continue;
}
}
if (resType.equals("java.net.URL"))
{
// URL bindings
if (ref.getResURL() != null)
{
// The URL string was given by the res-url
log.debug("Binding URL: " + ref.getRefName() + " to JDNI ENC as: " + ref.getResURL());
URL resURL = new URL(ref.getResURL());
Util.bind(envCtx, ref.getRefName(), resURL);
}
else
{
log.debug("Binding URL: " + ref.getRefName() + " to: " + finalName);
Object bind = null;
if (ref.getJndiName() != null)
{
// Was the url given as a jndi-name reference to link to it
bind = new LinkRef(finalName);
}
else
{
// The url string was given via a resource-name mapping
bind = new URL(finalName);
}
Util.bind(envCtx, ref.getRefName(), bind);
}
}
else
{
// Resource Manager bindings, should validate the type...
log.debug("Binding resource manager: " + ref.getRefName() + " to JDNI ENC as: " + finalName);
Util.bind(envCtx, ref.getRefName(), new LinkRef(finalName));
}
}
}
// Bind resource env references
{
Iterator i = beanMetaData.getResourceEnvReferences();
while (i.hasNext())
{
ResourceEnvRefMetaData resRef = (ResourceEnvRefMetaData)i.next();
String encName = resRef.getRefName();
String jndiName = resRef.getJndiName();
// Should validate the type...
log.debug("Binding env resource: " + encName + " to JDNI ENC as: " + jndiName);
Util.bind(envCtx, encName, new LinkRef(jndiName));
}
}
// Bind message destination references
{
Iterator i = beanMetaData.getMessageDestinationReferences();
while (i.hasNext())
{
MessageDestinationRefMetaData ref = (MessageDestinationRefMetaData)i.next();
String refName = ref.getRefName();
String jndiName = ref.getJNDIName();
String link = ref.getLink();
if (link != null)
{
if (jndiName == null)
{
MessageDestinationMetaData messageDestination = getMessageDestination(link);
if (messageDestination == null)
throw new DeploymentException("message-destination-ref '" + refName + "' message-destination-link '" + link
+ "' not found and no jndi-name in jboss.xml");
else
{
String linkJNDIName = messageDestination.getJndiName();
if (linkJNDIName == null)
log.warn("message-destination '" + link + "' has no jndi-name in jboss.xml");
else
jndiName = linkJNDIName;
}
}
else
log.warn("message-destination-ref '" + refName + "' ignoring message-destination-link '" + link + "' because it has a jndi-name in jboss.xml");
}
else if (jndiName == null)
throw new DeploymentException("message-destination-ref '" + refName + "' has no message-destination-link in ejb-jar.xml and no jndi-name in jboss.xml");
Util.bind(envCtx, refName, new LinkRef(jndiName));
}
}
// Create a java:comp/env/security/security-domain link to the container
// or application security-domain if one exists so that access to the
// security manager can be made without knowing the global jndi name.
String securityDomain = metaData.getContainerConfiguration().getSecurityDomain();
if (securityDomain == null)
securityDomain = metaData.getApplicationMetaData().getSecurityDomain();
if (securityDomain != null)
{
//JBAS-6060: Tolerate a Security Domain configuration without the java:/jaas prefix
if(securityDomain.startsWith(SecurityConstants.JAAS_CONTEXT_ROOT) == false)
securityDomain = SecurityConstants.JAAS_CONTEXT_ROOT + "/" + securityDomain;
log.debug("Binding securityDomain: " + securityDomain + " to JDNI ENC as: security/security-domain");
Util.bind(envCtx, "security/security-domain", new LinkRef(securityDomain));
Util.bind(envCtx, "security/subject", new LinkRef(securityDomain + "/subject"));
Util.bind(envCtx, "security/realmMapping", new LinkRef(securityDomain + "/realmMapping"));
Util.bind(envCtx, "security/authorizationMgr", new LinkRef(securityDomain + "/authorizationMgr"));
}
log.debug("End java:comp/env for EJB: " + beanMetaData.getEjbName());
}
// in src/main/java/org/jboss/ejb/Container.java
private void teardownEnvironment() throws Exception
{
Context ctx = (Context)new InitialContext().lookup("java:comp");
ctx.unbind("env");
log.debug("Removed bindings from java:comp/env for EJB: " + getBeanMetaData().getEjbName());
ctx.unbind("TransactionSynchronizationRegistry");
log.debug("Unbound java:comp/TransactionSynchronizationRegistry for EJB: " + getBeanMetaData().getEjbName());
try
{
NonSerializableFactory.unbind("ORB");
log.debug("Unbound java:comp/ORB for EJB: " + getBeanMetaData().getEjbName());
NonSerializableFactory.unbind("HandleDelegate");
log.debug("Unbound java:comp/HandleDelegate for EJB: " + getBeanMetaData().getEjbName());
}
catch (NamingException ignored)
{
}
}
// in src/main/java/org/jboss/ejb/Container.java
protected void rethrow(Exception e) throws Exception
{
if (e instanceof IllegalAccessException)
{
// Throw this as a bean exception...(?)
throw new EJBException(e);
}
else if (e instanceof InvocationTargetException)
{
Throwable t = ((InvocationTargetException)e).getTargetException();
if (t instanceof EJBException)
{
throw (EJBException)t;
}
else if (t instanceof Exception)
{
throw (Exception)t;
}
else if (t instanceof Error)
{
throw (Error)t;
}
else
{
throw new NestedError("Unexpected Throwable", t);
}
}
throw e;
}
// in src/main/java/org/jboss/ejb/Container.java
public Object run() throws Exception
{
Object rtnValue = server.invoke(target, method, args, sig);
return rtnValue;
}
// in src/main/java/org/jboss/ejb/Container.java
Object invoke(ObjectName target, String method, Object[] args, String[] sig) throws Exception
{
SecurityManager sm = System.getSecurityManager();
Object rtnValue = null;
if (sm == null)
{
// Direct invocation on MBeanServer
rtnValue = server.invoke(target, method, args, sig);
}
else
{
try
{
// Encapsulate the invocation in a PrivilegedExceptionAction
MBeanServerAction action = new MBeanServerAction(target, method, args, sig);
rtnValue = AccessController.doPrivileged(action);
}
catch (PrivilegedActionException e)
{
Exception ex = e.getException();
throw ex;
}
}
return rtnValue;
}
// in src/main/java/org/jboss/ejb/BeanLockManager.java
private BeanLock createLock(Object id) throws Exception
{
BeanLock lock = (BeanLock) lockClass.newInstance();
lock.setId(id);
lock.setTimeout(txTimeout);
lock.setContainer(container);
return lock;
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
protected void createService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Call default init
super.createService();
// Map the bean methods
Map map = new HashMap();
MessageDrivenMetaData mdMetaData = (MessageDrivenMetaData)metaData;
String type = mdMetaData.getMessagingType();
if(type == null || type.length() == 0)
type = MessageDrivenMetaData.DEFAULT_MESSAGING_TYPE;
Class clazz = getClassLoader().loadClass(type);
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++)
{
Method m = methods[i];
map.put(m, beanClass.getMethod(m.getName(), m.getParameterTypes()));
log.debug("Mapped " + m.getName() + " " + m.hashCode() + " to " + map.get(m));
}
if( TimedObject.class.isAssignableFrom( beanClass ) ) {
// Map ejbTimeout
map.put(
TimedObject.class.getMethod( "ejbTimeout", new Class[] { Timer.class } ),
beanClass.getMethod( "ejbTimeout", new Class[] { Timer.class } )
);
}
beanMapping = map;
// Try to register the instance pool as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "pool");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instancePool, poolName);
}
catch(Throwable t)
{
log.debug("Failed to register pool as mbean", t);
}
// Initialize pool
instancePool.setContainer(this);
instancePool.create();
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext();)
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
// Try to register the container invoker as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "invoker");
props.put("binding", invokerBinding);
ObjectName invokerName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(ci, invokerName);
}
catch(Throwable t)
{
log.debug("Failed to register invoker binding as mbean", t);
}
ci.create();
}
// Initialize the interceptor by calling the chain
Interceptor in = interceptor;
while (in != null)
{
in.setContainer(this);
in.create();
in = in.getNext();
}
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
protected void startService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Call default start
super.startService();
// Start the instance pool
instancePool.start();
// Start all interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.start();
in = in.getNext();
}
// Start container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext();)
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
ci.start();
}
// Restore persisted ejb timers
restoreTimers();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
protected void stopService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Call default stop
super.stopService();
// Stop container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext();)
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
ci.stop();
}
// Stop the instance pool
instancePool.stop();
// Stop all interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.stop();
in = in.getNext();
}
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
protected void destroyService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Destroy container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext();)
{
String invokerBinding = (String) it.next();
EJBProxyFactory ci = (EJBProxyFactory) proxyFactories.get(invokerBinding);
ci.destroy();
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "invoker");
props.put("binding", invokerBinding);
ObjectName invokerName = new ObjectName(containerName.getDomain(), props);
server.unregisterMBean(invokerName);
}
catch(Throwable ignore)
{
}
}
// Destroy the pool
instancePool.destroy();
instancePool.setContainer(null);
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "pool");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.unregisterMBean(poolName);
}
catch(Throwable ignore)
{
}
// Destroy all the interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.destroy();
in.setContainer(null);
in = in.getNext();
}
// Call default destroy
super.destroyService();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
public Object internalInvokeHome(Invocation mi)
throws Exception
{
throw new Error("invokeHome not valid for MessageDriven beans");
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
public Object internalInvoke(Invocation mi) throws Exception
{
SecurityContext cachedContext = null;
try
{
cachedContext = SecurityActions.getSecurityContext();
//For message driven beans, there is no security context
SecurityActions.setSecurityContext(null);
// Invoke through interceptors
return getInterceptor().invoke(mi);
}
finally
{
SecurityActions.setSecurityContext(cachedContext);
}
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
public Object invokeHome(Invocation mi) throws Exception
{
throw new Error("invokeHome not valid for MessageDriven beans");
}
// in src/main/java/org/jboss/ejb/MessageDrivenContainer.java
public Object invoke(Invocation mi)
throws Exception
{
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
// wire the transaction on the context,
// this is how the instance remember the tx
if (ctx.getTransaction() == null)
{
ctx.setTransaction(mi.getTransaction());
}
// Get method and instance to invoke upon
Method m = (Method) beanMapping.get(mi.getMethod());
if( m == null )
{
// This is a configuration error that should have been caught earlier
String msg = MessageDrivenContainer.this.getBeanMetaData().getEjbName()
+ " Invalid invocation, check your deployment packaging, interfaces, method=" + mi.getMethod();
throw new EJBException(msg);
}
// we have a method that needs to be done by a bean instance
try
{
messageCount++;
return mi.performCall(ctx.getInstance(), m, mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/ejb/plugins/EntityInstanceInterceptor.java
public Object invokeHome(Invocation mi)
throws Exception
{
// Get context
EntityContainer container = (EntityContainer) getContainer();
EntityEnterpriseContext ctx = (EntityEnterpriseContext) container.getInstancePool().get();
ctx.setTxAssociation(GlobalTxEntityMap.NOT_READY);
InstancePool pool = container.getInstancePool();
// Pass it to the method invocation
mi.setEnterpriseContext(ctx);
// Give it the transaction
ctx.setTransaction(mi.getTransaction());
// Set the current security information
ctx.setPrincipal(mi.getPrincipal());
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_HOME);
// Invoke through interceptors
Object obj = null;
Exception exception = null;
try
{
obj = getNext().invokeHome(mi);
// Is the context now with an identity? in which case we need to insert
if (ctx.getId() != null)
{
BeanLock lock = container.getLockManager().getLock(ctx.getCacheKey());
lock.sync(); // lock all access to BeanLock
try
{
// Check there isn't a context already in the cache
// e.g. commit-option B where the entity was
// created then removed externally
InstanceCache cache = container.getInstanceCache();
cache.remove(ctx.getCacheKey());
// marcf: possible race on creation and usage
// insert instance in cache,
cache.insert(ctx);
}
finally
{
lock.releaseSync();
container.getLockManager().removeLockRef(ctx.getCacheKey());
}
// we are all done
return obj;
}
}
catch (Exception e)
{
exception = e;
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
ctx.setTransaction(null);
// EntityCreateInterceptor will access ctx if it is not null and call postCreate
mi.setEnterpriseContext(null);
// if we get to here with a null exception then our invocation is
// just a home invocation. Return our instance to the instance pool
if (exception == null)
{
container.getInstancePool().free(ctx);
return obj;
}
if (exception instanceof RuntimeException)
{
// if we get to here with a RuntimeException, we have a system exception.
// EJB 2.1 section 18.3.1 says we need to discard our instance.
pool.discard(ctx);
}
else
{
// if we get to here with an Exception, we have an application exception.
// EJB 2.1 section 18.3.1 says we can keep the instance. We need to return
// our instance to the instance pool so we dont get a memory leak.
pool.free(ctx);
}
throw exception;
}
// in src/main/java/org/jboss/ejb/plugins/EntityInstanceInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
boolean trace = log.isTraceEnabled();
// The key
Object key = mi.getId();
// The context
EntityEnterpriseContext ctx;
try
{
ctx = (EntityEnterpriseContext) container.getInstanceCache().get(key);
}
catch (NoSuchObjectException e)
{
if (mi.isLocal())
throw new NoSuchObjectLocalException(e.getMessage());
else
throw e;
}
catch (EJBException e)
{
throw e;
}
catch (RemoteException e)
{
throw e;
}
catch (Exception e)
{
InvocationType type = mi.getType();
boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
if (isLocal)
throw new EJBException("Unable to get an instance from the pool/cache", e);
else
throw new RemoteException("Unable to get an intance from the pool/cache", e);
}
if (trace) log.trace("Begin invoke, key=" + key);
// Associate transaction, in the new design the lock already has the transaction from the
// previous interceptor
// Don't set the transction if a read-only method. With a read-only method, the ctx can be shared
// between multiple transactions.
Transaction tx = mi.getTransaction();
if (!container.isReadOnly())
{
Method method = mi.getMethod();
if (method == null ||
!container.getBeanMetaData().isMethodReadOnly(method.getName()))
{
ctx.setTransaction(tx);
}
}
// Set the current security information
ctx.setPrincipal(mi.getPrincipal());
// Set the JACC EnterpriseBean PolicyContextHandler data
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx.getInstance());
// Set context on the method invocation
mi.setEnterpriseContext(ctx);
if (ejbTimeout.equals(mi.getMethod()))
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_TIMEOUT);
else
AllowedOperationsAssociation.pushInMethodFlag(IN_BUSINESS_METHOD);
Throwable exceptionThrown = null;
boolean discardContext = false;
try
{
Object obj = getNext().invoke(mi);
return obj;
}
catch (RemoteException e)
{
exceptionThrown = e;
discardContext = true;
throw e;
}
catch (RuntimeException e)
{
exceptionThrown = e;
discardContext = true;
throw e;
}
catch (Error e)
{
exceptionThrown = e;
discardContext = true;
throw e;
}
catch (Exception e)
{
exceptionThrown = e;
throw e;
}
catch (Throwable e)
{
exceptionThrown = e;
discardContext = true;
throw new NestedRuntimeException(e);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
// Make sure we clear the transaction on an error before synchronization.
// But avoid a race with a transaction rollback on a synchronization
// that may have moved the context onto a different transaction
if (exceptionThrown != null && tx != null)
{
Transaction ctxTx = ctx.getTransaction();
if (tx.equals(ctxTx) && ctx.hasTxSynchronization() == false)
ctx.setTransaction(null);
}
// If an exception has been thrown,
if (exceptionThrown != null &&
// if tx, the ctx has been registered in an InstanceSynchronization.
// that will remove the context, so we shouldn't.
// if no synchronization then we need to do it by hand
// But not for application exceptions
!ctx.hasTxSynchronization() && discardContext)
{
// Discard instance
// EJB 1.1 spec 12.3.1
container.getInstanceCache().remove(key);
if (trace) log.trace("Ending invoke, exceptionThrown, ctx=" + ctx, exceptionThrown);
}
else if (ctx.getId() == null)
{
// The key from the Invocation still identifies the right cachekey
container.getInstanceCache().remove(key);
if (trace) log.trace("Ending invoke, cache removal, ctx=" + ctx);
// no more pool return
}
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
if (trace) log.trace("End invoke, key=" + key + ", ctx=" + ctx);
}// end finally
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
protected void createService() throws Exception
{
this.beans = new HashMap(1000);
String ejbName = con.getBeanMetaData ().getEjbName ();
idField = con.getBeanClass ().getField ("id");
log.debug("Using id field: " + idField);
// Lookup the isModified method if it exists
try
{
isModified = con.getBeanClass().getMethod("isModified", new Class[0]);
if (!isModified.getReturnType().equals(Boolean.TYPE)) {
isModified = null; // Has to have "boolean" as return type!
log.warn("Found isModified method, but return type is not boolean; ignoring");
}
else {
log.debug("Using isModified method: " + isModified);
}
}
catch (NoSuchMethodException ignored) {}
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
protected void stopService() throws Exception
{
this.beans.clear();
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public Object createBeanClassInstance () throws Exception
{
return con.getBeanClass ().newInstance ();
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public Object createEntity (Method m, Object[] args, EntityEnterpriseContext ctx) throws Exception
{
try
{
Object id = idField.get (ctx.getInstance ());
// Check exist
if (this.beans.containsKey (id))
throw new javax.ejb.DuplicateKeyException ("Already exists: "+id);
// Store to file
storeEntity (id, ctx.getInstance ());
return id;
}
catch (IllegalAccessException e)
{
throw new javax.ejb.CreateException ("Could not create entity: "+e);
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public Object postCreateEntity(final Method m,
final Object[] args,
final EntityEnterpriseContext ctx)
throws Exception
{
return null;
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public Object findEntity (Method finderMethod, Object[] args, EntityEnterpriseContext instance, GenericEntityObjectFactory factory)
throws Exception
{
if (finderMethod.getName ().equals ("findByPrimaryKey"))
{
if (!this.beans.containsKey (args[0]))
throw new javax.ejb.FinderException (args[0]+" does not exist");
return factory.getEntityEJBObject(args[0]);
}
return null;
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public Collection findEntities(final Method finderMethod,
final Object[] args,
final EntityEnterpriseContext instance,
GenericEntityObjectFactory factory)
throws Exception
{
if (finderMethod.getName ().equals ("findAll"))
{
return GenericEntityObjectFactory.UTIL.getEntityCollection(factory, this.beans.keySet());
}
else
{
// we only support find all
return Collections.EMPTY_LIST;
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public boolean isStoreRequired (EntityEnterpriseContext ctx) throws Exception
{
if(isModified == null)
{
return true;
}
Boolean modified = (Boolean) isModified.invoke (ctx.getInstance (), new Object[0]);
return modified.booleanValue ();
}
// in src/main/java/org/jboss/ejb/plugins/CMPInMemoryPersistenceManager.java
public boolean isModified(EntityEnterpriseContext ctx) throws Exception
{
return isStoreRequired(ctx);
}
// in src/main/java/org/jboss/ejb/plugins/EntityLockInterceptor.java
public Object invokeHome(Invocation mi)
throws Exception
{
// Invoke through interceptors
return getNext().invokeHome(mi);
}
// in src/main/java/org/jboss/ejb/plugins/EntityLockInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
// The key.
Object key = mi.getId();
// The lock.
BeanLock lock ;
boolean threadIsScheduled = false;
boolean trace = log.isTraceEnabled();
if( trace ) log.trace("Begin invoke, key="+key);
lock = container.getLockManager().getLock(key);
try
{
lock.schedule(mi);
try {
return getNext().invoke(mi);
}
finally
{
// we are done with the method, decrease the count, if it reaches 0 it will wake up
// the next thread
lock.sync();
lock.endInvocation(mi);
lock.releaseSync();
}
}
finally
{
// We are done with the lock in general
container.getLockManager().removeLockRef(key);
if( trace ) log.trace("End invoke, key="+key);
}
}
// in src/main/java/org/jboss/ejb/plugins/SecurityProxyInterceptor.java
public void start() throws Exception
{
super.start();
}
// in src/main/java/org/jboss/ejb/plugins/SecurityProxyInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
// Apply any custom security checks
if( securityProxy != null )
{
EJBContext ctx = null;
EnterpriseContext ectx = (EnterpriseContext)mi.getEnterpriseContext();
if( ectx != null )
ctx = ectx.getEJBContext();
Object[] args = mi.getArguments();
securityProxy.setEJBContext(ctx);
try
{
securityProxy.invokeHome(mi.getMethod(), args);
}
catch(SecurityException e)
{
Principal principal = mi.getPrincipal();
String msg = "SecurityProxy.invokeHome exception, principal=" + principal;
log.error(msg, e);
throw e;
}
}
return getNext().invokeHome(mi);
}
// in src/main/java/org/jboss/ejb/plugins/SecurityProxyInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
// Apply any custom security checks
if( securityProxy != null )
{
EnterpriseContext ectx = (EnterpriseContext)mi.getEnterpriseContext();
Object bean = ectx.getInstance();
EJBContext ctx = ectx.getEJBContext();
Object[] args = mi.getArguments();
securityProxy.setEJBContext(ctx);
try
{
securityProxy.invoke(mi.getMethod(), args, bean);
}
catch(SecurityException e)
{
Principal principal = mi.getPrincipal();
String msg = "SecurityProxy.invoke exception, principal="+principal;
log.error(msg, e);
throw e;
}
}
return getNext().invoke(mi);
}
// in src/main/java/org/jboss/ejb/plugins/inflow/JBossMessageEndpointFactory.java
protected void startService() throws Exception
{
// Lets take a reference to our metadata
metaData = (MessageDrivenMetaData) container.getBeanMetaData();
// Resolve the message listener
resolveMessageListener();
// Resolve the resource adapter
resolveResourceAdapter();
// Create the activation config
createActivationSpec();
// Set up proxy parameters
setupProxyParameters();
// Activate
activate();
}
// in src/main/java/org/jboss/ejb/plugins/inflow/JBossMessageEndpointFactory.java
protected void stopService() throws Exception
{
// Deactivate
deactivate();
}
// in src/main/java/org/jboss/ejb/plugins/inflow/JBossMessageEndpointFactory.java
public void startDelivery() throws Exception
{
if (getState() != STARTED)
throw new IllegalStateException("The MDB is not started");
if (deliveryActive.getAndSet(true))
return;
activate();
}
// in src/main/java/org/jboss/ejb/plugins/inflow/JBossMessageEndpointFactory.java
public void stopDelivery() throws Exception
{
stopDelivery(false);
}
// in src/main/java/org/jboss/ejb/plugins/inflow/JBossMessageEndpointFactory.java
public void stopDelivery(boolean asynch) throws Exception
{
if (getState() != STARTED)
throw new IllegalStateException("The MDB is not started");
if (deliveryActive.getAndSet(false) == false)
return;
if (asynch)
{
new Thread("StopDelivery: " + getServiceName())
{
public void run()
{
deactivate();
}
}.start();
}
else
{
deactivate();
}
}
// in src/main/java/org/jboss/ejb/plugins/StatelessSessionInstancePool.java
protected void createService() throws Exception
{
super.createService();
// for SLSB, we *do* pool
this.reclaim = true;
}
// in src/main/java/org/jboss/ejb/plugins/StatelessSessionInstancePool.java
protected EnterpriseContext create(Object instance)
throws Exception
{
return new StatelessSessionEnterpriseContext(instance, getContainer());
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/uuid/UUIDKeyGeneratorFactory.java
public KeyGenerator getKeyGenerator()
throws Exception
{
return new UUIDKeyGenerator();
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/hilo/HiLoKeyGeneratorFactory.java
public void setDataSource(ObjectName dataSource) throws Exception
{
if(getState() == STARTED && !dataSource.equals(this.dataSource))
{
ds = lookupDataSource(dataSource);
}
this.dataSource = dataSource;
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/hilo/HiLoKeyGeneratorFactory.java
public void setTableName(String tableName)
throws Exception
{
if(getState() == STARTED && !tableName.equals(this.tableName))
{
initSequence(tableName, sequenceColumn, sequenceName, idColumnName);
}
this.tableName = tableName;
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/hilo/HiLoKeyGeneratorFactory.java
public KeyGenerator getKeyGenerator() throws Exception
{
return new HiLoKeyGenerator(ds, tableName, sequenceColumn, sequenceName, idColumnName, selectHiSql, blockSize, tm);
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/hilo/HiLoKeyGeneratorFactory.java
public void startService()
throws Exception
{
Context ctx = new InitialContext();
// bind the factory
Util.rebind(ctx, getFactoryName(), this);
tm = (TransactionManager)ctx.lookup("java:/TransactionManager");
ds = lookupDataSource(dataSource);
initSequence(tableName, sequenceColumn, sequenceName, idColumnName);
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/hilo/HiLoKeyGeneratorFactory.java
public void stopService()
throws Exception
{
if(dropTable)
{
dropTableIfExists(tableName);
}
ds = null;
tm = null;
// unbind the factory
Context ctx = new InitialContext();
Util.unbind(ctx, getFactoryName());
}
// in src/main/java/org/jboss/ejb/plugins/keygenerator/hilo/HiLoKeyGeneratorFactory.java
private DataSource lookupDataSource(ObjectName dataSource)
throws Exception
{
try
{
String dsJndi = (String) server.getAttribute(dataSource, "BindName");
return (DataSource)new InitialContext().lookup(dsJndi);
}
catch(NamingException e)
{
throw new Exception("Failed to lookup data source: " + dataSource);
}
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionSecurityInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
if(ctx == null)
throw new IllegalStateException("EJBContext is null");
//Set the current security information
ctx.setPrincipal(mi.getPrincipal());
try
{
// Invoke through interceptors
return getNext().invoke(mi);
}
finally
{
}
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionSecurityInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
Method getEJBObject = Handle.class.getMethod("getEJBObject", new Class[0]);
//Invocation on the handle, we don't need a bean instance
if (getEJBObject.equals(mi.getMethod()))
return getNext().invokeHome(mi);
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
if(ctx == null)
throw new IllegalStateException("EJBContext is null");
//Set the current security information
ctx.setPrincipal(mi.getPrincipal());
try
{
// Invoke through interceptors
return getNext().invokeHome(mi);
}
finally
{
}
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public void create()
throws Exception
{
ejbLoad = EntityBean.class.getMethod("ejbLoad", new Class[0]);
ejbStore = EntityBean.class.getMethod("ejbStore", new Class[0]);
ejbActivate = EntityBean.class.getMethod("ejbActivate", new Class[0]);
ejbPassivate = EntityBean.class.getMethod("ejbPassivate", new Class[0]);
ejbRemove = EntityBean.class.getMethod("ejbRemove", new Class[0]);
// Create cache of create methods
if (con.getHomeClass() != null)
{
Method[] methods = con.getHomeClass().getMethods();
createMethodCache( methods );
}
if (con.getLocalHomeClass() != null)
{
Method[] methods = con.getLocalHomeClass().getMethods();
createMethodCache( methods );
}
try
{
isModified = con.getBeanClass().getMethod("isModified", new Class[0]);
if (!isModified.getReturnType().equals(Boolean.TYPE))
isModified = null; // Has to have "boolean" as return type!
}
catch (NoSuchMethodException ignored) {}
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public Object createBeanClassInstance() throws Exception {
return con.getBeanClass().newInstance();
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public void createEntity(
Method m,
Object[] args,
EntityEnterpriseContext ctx)
throws Exception
{
Object id = null;
try
{
// Call ejbCreate<METHOD)
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_CREATE);
Method createMethod = (Method)createMethods.get(m);
id = createMethod.invoke(ctx.getInstance(), args);
} catch (IllegalAccessException e)
{
// Throw this as a bean exception...(?)
throw new EJBException(e);
} catch (InvocationTargetException ite)
{
Throwable e = ite.getTargetException();
if (e instanceof CreateException)
{
// Rethrow exception
throw (CreateException)e;
}
else if (e instanceof RemoteException)
{
// Rethrow exception
throw (RemoteException)e;
}
else if (e instanceof EJBException)
{
// Rethrow exception
throw (EJBException)e;
}
else if (e instanceof RuntimeException)
{
// Wrap runtime exceptions
throw new EJBException((Exception)e);
}
else if(e instanceof Exception)
{
throw (Exception)e;
}
else
{
throw (Error)e;
}
}
finally{
AllowedOperationsAssociation.popInMethodFlag();
}
// set the id
ctx.setId(id);
// Create a new CacheKey
Object cacheKey = ((EntityCache) con.getInstanceCache()).createCacheKey( id );
// Give it to the context
ctx.setCacheKey(cacheKey);
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public void postCreateEntity(
Method m,
Object[] args,
EntityEnterpriseContext ctx)
throws Exception
{
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_POST_CREATE);
Method postCreateMethod = (Method)postCreateMethods.get(m);
postCreateMethod.invoke(ctx.getInstance(), args);
} catch (IllegalAccessException e)
{
// Throw this as a bean exception...(?)
throw new EJBException(e);
} catch (InvocationTargetException ite)
{
Throwable e = ite.getTargetException();
if (e instanceof CreateException)
{
// Rethrow exception
throw (CreateException)e;
}
else if (e instanceof RemoteException)
{
// Rethrow exception
throw (RemoteException)e;
}
else if (e instanceof EJBException)
{
// Rethrow exception
throw (EJBException)e;
}
else if (e instanceof RuntimeException)
{
// Wrap runtime exceptions
throw new EJBException((Exception)e);
}
else if(e instanceof Exception)
{
throw (Exception)e;
}
else
{
throw (Error)e;
}
}
finally{
AllowedOperationsAssociation.popInMethodFlag();
}
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public Object findEntity(Method finderMethod, Object[] args, EntityEnterpriseContext ctx, GenericEntityObjectFactory factory)
throws Exception
{
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_FIND);
// call the finder method
Object objectId = callFinderMethod(finderMethod, args, ctx);
final Object cacheKey = ((EntityCache)con.getInstanceCache()).createCacheKey( objectId );
return factory.getEntityEJBObject(cacheKey);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public Collection findEntities(Method finderMethod, Object[] args, EntityEnterpriseContext ctx, GenericEntityObjectFactory factory)
throws Exception
{
// call the finder method
Object result;
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_FIND);
result = callFinderMethod(finderMethod, args, ctx);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
if (result == null)
{
// for EJB 1.0 compliance
// if the bean couldn't find any matching entities
// it returns null, so we return an empty collection
return new ArrayList();
}
if (result instanceof java.util.Enumeration)
{
// to preserve 1.0 spec compatiblity
ArrayList array = new ArrayList();
Enumeration e = (Enumeration) result;
while (e.hasMoreElements() == true)
{
// Wrap a cache key around the given object id/primary key
final Object cacheKey = ((EntityCache) con.getInstanceCache()).createCacheKey(e.nextElement());
Object o = factory.getEntityEJBObject(cacheKey);
array.add(o);
}
return array;
}
else if (result instanceof java.util.Collection)
{
ArrayList array = new ArrayList(((Collection) result).size());
Iterator i = ((Collection) result).iterator();
while (i.hasNext())
{
// Wrap a cache key around the given object id/primary key
final Object cacheKey = ((EntityCache) con.getInstanceCache()).createCacheKey(i.next());
Object o = factory.getEntityEJBObject(cacheKey);
array.add(o);
}
return array;
}
else
{
// so we received something that's not valid
// throw an exception reporting it
throw new EJBException("result of finder method is not a valid " +
"return type: " + result.getClass());
}
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public boolean isStoreRequired(EntityEnterpriseContext ctx) throws Exception
{
if(isModified == null)
{
return true;
}
Boolean modified = (Boolean) isModified.invoke(ctx.getInstance(), EMPTY_OBJECT_ARRAY);
return modified.booleanValue();
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
public boolean isModified(EntityEnterpriseContext ctx) throws Exception
{
return isStoreRequired(ctx);
}
// in src/main/java/org/jboss/ejb/plugins/BMPPersistenceManager.java
private Object callFinderMethod(Method finderMethod, Object[] args, EntityEnterpriseContext ctx)
throws Exception
{
// get the finder method
Method callMethod = (Method)finderMethods.get(finderMethod);
if (callMethod == null)
{
throw new EJBException("couldn't find finder method in bean class. " +
finderMethod.toString());
}
// invoke the finder method
Object result = null;
try
{
result = callMethod.invoke(ctx.getInstance(), args);
} catch (IllegalAccessException e)
{
// Throw this as a bean exception...(?)
throw new EJBException(e);
} catch (InvocationTargetException ite)
{
Throwable e = ite.getTargetException();
if (e instanceof FinderException)
{
// Rethrow exception
throw (FinderException)e;
}
else if (e instanceof RemoteException)
{
// Rethrow exception
throw (RemoteException)e;
}
else if (e instanceof EJBException)
{
// Rethrow exception
throw (EJBException)e;
}
else if (e instanceof RuntimeException)
{
// Wrap runtime exceptions
throw new EJBException((Exception)e);
}
else if(e instanceof Exception)
{
throw (Exception)e;
}
else
{
throw (Error)e;
}
}
return result;
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
protected void createService() throws Exception
{
// Initialize the dataStore
String ejbName = con.getBeanMetaData().getEjbName();
// Get the system data directory
File dir = new File(ServerConfigLocator.locate().getServerTempLocation().toURI());
// Setup the reference to the session data store directory
dir = new File(dir, storeDirName);
// ejbName is not unique across all deployments, so use a unique token
dir = new File(dir, ejbName + "-" + new UID().toString());
storeDir = dir;
log.debug("Storing sessions for '" + ejbName + "' in: " + storeDir);
// if the directory does not exist then try to create it
if( !storeDir.exists() )
{
if( MkdirsFileAction.mkdirs(storeDir) == false )
{
throw new IOException("Failed to create directory: " + storeDir);
}
}
// make sure we have a directory
if( !storeDir.isDirectory() )
{
throw new IOException("File exists where directory expected: " + storeDir);
}
// make sure we can read and write to it
if( !storeDir.canWrite() || !storeDir.canRead() )
{
throw new IOException("Directory must be readable and writable: " + storeDir);
}
// Purge state session state files, should be none, due to unique directory
purgeAllSessionData();
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
protected void destroyService() throws Exception
{
// Purge data and attempt to delete directory
purgeAllSessionData();
// Nuke the directory too if purge is enabled
if( purgeEnabled && !storeDir.delete() )
{
log.warn("Failed to delete session state storage directory: " + storeDir);
}
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
public Object createId(StatefulSessionEnterpriseContext ctx)
throws Exception
{
return new UID();
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
public void createdSession(StatefulSessionEnterpriseContext ctx)
throws Exception
{
// nothing
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
public Object run() throws Exception
{
FileInputStream fis = new FileInputStream(file);
return fis;
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionFilePersistenceManager.java
public Object run() throws Exception
{
FileOutputStream fis = new FileOutputStream(file);
return fis;
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorCMT.java
public void create() throws Exception
{
super.create();
BeanMetaData bmd = getContainer().getBeanMetaData();
exceptionRollback = bmd.getExceptionRollback();
if (exceptionRollback == false)
exceptionRollback = bmd.getApplicationMetaData().getExceptionRollback();
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorCMT.java
public Object invokeHome(Invocation invocation) throws Exception
{
Transaction oldTransaction = invocation.getTransaction();
for (int i = 0; i < MAX_RETRIES; i++)
{
try
{
return runWithTransactions(invocation);
}
catch (Exception ex)
{
checkRetryable(i, ex, oldTransaction);
}
}
throw new RuntimeException("Unreachable");
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorCMT.java
public Object invoke(Invocation invocation) throws Exception
{
Transaction oldTransaction = invocation.getTransaction();
for (int i = 0; i < MAX_RETRIES; i++)
{
try
{
return runWithTransactions(invocation);
}
catch (Exception ex)
{
checkRetryable(i, ex, oldTransaction);
}
}
throw new RuntimeException("Unreachable");
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorCMT.java
private void checkRetryable(int i, Exception ex, Transaction oldTransaction) throws Exception
{
// if oldTransaction != null this means tx was propagated over the wire
// and we cannot retry it
if (i + 1 >= MAX_RETRIES || oldTransaction != null) throw ex;
// Keep ADE check for backward compatibility
ApplicationDeadlockException deadlock = isADE(ex);
if (deadlock != null)
{
if (!deadlock.retryable()) throw deadlock;
log.debug(deadlock.getMessage() + " retrying tx " + (i + 1));
}
else if (retryHandlers != null)
{
boolean retryable = false;
for (int j = 0; j < retryHandlers.length; j++)
{
retryable = retryHandlers[j].retry(ex);
if (retryable) break;
}
if (!retryable) throw ex;
log.debug(ex.getMessage() + " retrying tx " + (i + 1));
}
else
{
throw ex;
}
Thread.sleep(random.nextInt(1 + i), random.nextInt(1000));
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorCMT.java
private Object runWithTransactions(Invocation invocation) throws Exception
{
// Old transaction is the transaction that comes with the MI
Transaction oldTransaction = invocation.getTransaction();
// New transaction is the new transaction this might start
Transaction newTransaction = null;
boolean trace = log.isTraceEnabled();
if( trace )
log.trace("Current transaction in MI is " + oldTransaction);
InvocationType type = invocation.getType();
byte transType = container.getBeanMetaData().getTransactionMethod(invocation.getMethod(), type);
if ( trace )
printMethod(invocation.getMethod(), transType);
// Thread arriving must be clean (jboss doesn't set the thread
// previously). However optimized calls come with associated
// thread for example. We suspend the thread association here, and
// resume in the finally block of the following try.
Transaction threadTx = tm.suspend();
if( trace )
log.trace("Thread came in with tx " + threadTx);
try
{
switch (transType)
{
case MetaData.TX_NOT_SUPPORTED:
{
// Do not set a transaction on the thread even if in MI, just run
try
{
invocation.setTransaction(null);
return invokeNext(invocation, false);
}
finally
{
invocation.setTransaction(oldTransaction);
}
}
case MetaData.TX_REQUIRED:
{
int oldTimeout = 0;
Transaction theTransaction = oldTransaction;
if (oldTransaction == null)
{ // No tx running
// Create tx
oldTimeout = startTransaction(invocation);
// get the tx
newTransaction = tm.getTransaction();
if( trace )
log.trace("Starting new tx " + newTransaction);
// Let the method invocation know
invocation.setTransaction(newTransaction);
theTransaction = newTransaction;
}
else
{
// We have a tx propagated
// Associate it with the thread
tm.resume(oldTransaction);
}
// Continue invocation
try
{
Object result = invokeNext(invocation, oldTransaction != null);
checkTransactionStatus(theTransaction, type);
return result;
}
finally
{
if( trace )
log.trace("TxInterceptorCMT: In finally");
// Only do something if we started the transaction
if (newTransaction != null)
endTransaction(invocation, newTransaction, oldTransaction, oldTimeout);
else
tm.suspend();
}
}
case MetaData.TX_SUPPORTS:
{
// Associate old transaction with the thread
// Some TMs cannot resume a null transaction and will throw
// an exception (e.g. Tyrex), so make sure it is not null
if (oldTransaction != null)
{
tm.resume(oldTransaction);
}
try
{
Object result = invokeNext(invocation, oldTransaction != null);
if (oldTransaction != null)
checkTransactionStatus(oldTransaction, type);
return result;
}
finally
{
tm.suspend();
}
// Even on error we don't do anything with the tx,
// we didn't start it
}
case MetaData.TX_REQUIRES_NEW:
{
// Always begin a transaction
int oldTimeout = startTransaction(invocation);
// get it
newTransaction = tm.getTransaction();
// Set it on the method invocation
invocation.setTransaction(newTransaction);
// Continue invocation
try
{
Object result = invokeNext(invocation, false);
checkTransactionStatus(newTransaction, type);
return result;
}
finally
{
// We started the transaction for sure so we commit or roll back
endTransaction(invocation, newTransaction, oldTransaction, oldTimeout);
}
}
case MetaData.TX_MANDATORY:
{
if (oldTransaction == null)
{
if (type == InvocationType.LOCAL ||
type == InvocationType.LOCALHOME)
{
throw new TransactionRequiredLocalException(
"Transaction Required");
}
else
{
throw new TransactionRequiredException(
"Transaction Required");
}
}
// Associate it with the thread
tm.resume(oldTransaction);
try
{
Object result = invokeNext(invocation, true);
checkTransactionStatus(oldTransaction, type);
return result;
}
finally
{
tm.suspend();
}
}
case MetaData.TX_NEVER:
{
if (oldTransaction != null)
{
throw new EJBException("Transaction not allowed");
}
return invokeNext(invocation, false);
}
default:
log.error("Unknown TX attribute "+transType+" for method"+invocation.getMethod());
}
}
finally
{
// IN case we had a Tx associated with the thread reassociate
if (threadTx != null)
tm.resume(threadTx);
}
return null;
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorCMT.java
private int startTransaction(final Invocation invocation) throws Exception
{
// Get the old timeout and set any new timeout
int oldTimeout = -1;
if (tm instanceof TransactionTimeoutConfiguration)
{
oldTimeout = ((TransactionTimeoutConfiguration) tm).getTransactionTimeout();
int newTimeout = container.getBeanMetaData().getTransactionTimeout(invocation.getMethod());
tm.setTransactionTimeout(newTimeout);
}
tm.begin();
return oldTimeout;
}
// in src/main/java/org/jboss/ejb/plugins/EntityInstanceCache.java
public void remove(String id)
throws Exception
{
EntityMetaData metaData = (EntityMetaData) m_container.getBeanMetaData();
String primKeyClass = metaData.getPrimaryKeyClass();
Object key = PropertyEditors.convertValue(id, primKeyClass);
remove(key);
}
// in src/main/java/org/jboss/ejb/plugins/EntityInstanceCache.java
protected EnterpriseContext acquireContext() throws Exception
{
return m_container.getInstancePool().get();
}
// in src/main/java/org/jboss/ejb/plugins/SecurityActions.java
public Object run() throws Exception
{
return (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
}
// in src/main/java/org/jboss/ejb/plugins/SecurityActions.java
static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain)
throws PrivilegedActionException
{
AccessController.doPrivileged(new PrivilegedExceptionAction(){
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(p, cred, null, domain);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}});
}
// in src/main/java/org/jboss/ejb/plugins/SecurityActions.java
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(p, cred, null, domain);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}
// in src/main/java/org/jboss/ejb/plugins/SecurityActions.java
static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain,
final Subject subject) throws PrivilegedActionException
{
AccessController.doPrivileged(new PrivilegedExceptionAction(){
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
sc.getUtil().createSubjectInfo(p, cred, subject);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}});
}
// in src/main/java/org/jboss/ejb/plugins/SecurityActions.java
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
sc.getUtil().createSubjectInfo(p, cred, subject);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionInstancePool.java
protected EnterpriseContext create(Object instance)
throws Exception
{
// The instance is created by the caller and is a newInstance();
return new StatefulSessionEnterpriseContext(instance, getContainer());
}
// in src/main/java/org/jboss/ejb/plugins/InvalidableEntityInstanceCache.java
public void start() throws Exception
{
super.start();
log.debug("Starting InvalidableEntityInstanceCache...");
EntityMetaData emd = ((EntityMetaData) this.getContainer().getBeanMetaData());
boolean participateInDistInvalidations = emd.doDistributedCacheInvalidations();
byte co = emd.getContainerConfiguration().getCommitOption();
if (participateInDistInvalidations &&
(co == ConfigurationMetaData.A_COMMIT_OPTION || co == ConfigurationMetaData.D_COMMIT_OPTION)
)
{
// we are interested in receiving cache invalidation callbacks
//
String groupName = emd.getDistributedCacheInvalidationConfig().getInvalidationGroupName();
String imName = emd.getDistributedCacheInvalidationConfig().getInvalidationManagerName();
this.invalMgr = (InvalidationManagerMBean) Registry.lookup(imName);
this.ig = this.invalMgr.getInvalidationGroup(groupName);
this.ig.register(this);
this.isTraceEnabled = log.isTraceEnabled();
}
}
// in src/main/java/org/jboss/ejb/plugins/lock/NoLock.java
public void schedule(Invocation mi)
throws Exception
{
return;
}
// in src/main/java/org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java
protected boolean isTxExpired(Transaction miTx) throws Exception
{
return TxUtils.isRollback(miTx);
}
// in src/main/java/org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java
public void schedule(Invocation mi) throws Exception
{
boolean threadScheduled = false;
while (!threadScheduled)
{
/* loop on lock wakeup and restart trying to schedule */
threadScheduled = doSchedule(mi);
}
}
// in src/main/java/org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java
protected boolean doSchedule(Invocation mi)
throws Exception
{
boolean wasThreadScheduled = false;
Transaction miTx = mi.getTransaction();
boolean trace = log.isTraceEnabled();
this.sync();
try
{
if (trace) log.trace("Begin schedule, key=" + mi.getId());
if (isTxExpired(miTx))
{
log.error("Saw rolled back tx=" + miTx);
throw new RuntimeException("Transaction marked for rollback, possibly a timeout");
}
//Next test is independent of whether the context is locked or not, it is purely transactional
// Is the instance involved with another transaction? if so we implement pessimistic locking
long startWait = System.currentTimeMillis();
try
{
wasThreadScheduled = waitForTx(miTx, trace);
if (wasThreadScheduled && lockMonitor != null)
{
long endWait = System.currentTimeMillis() - startWait;
lockMonitor.finishedContending(endWait);
}
}
catch (Exception throwable)
{
if (lockMonitor != null && isTxExpired(miTx))
{
lockMonitor.increaseTimeouts();
}
if (lockMonitor != null)
{
long endWait = System.currentTimeMillis() - startWait;
lockMonitor.finishedContending(endWait);
}
throw throwable;
}
}
finally
{
if (miTx == null // non-transactional
&& wasThreadScheduled)
{
// if this non-transctional thread was
// scheduled in txWaitQueue, we need to call nextTransaction
// Otherwise, threads in txWaitQueue will never wake up.
nextTransaction();
}
this.releaseSync();
}
//If we reach here we are properly scheduled to go through so return true
return true;
}
// in src/main/java/org/jboss/ejb/plugins/lock/QueuedPessimisticEJBLock.java
protected boolean waitForTx(Transaction miTx, boolean trace) throws Exception
{
boolean intr = false;
try
{
boolean wasScheduled = false;
// Do we have a running transaction with the context?
// We loop here until either until success or until transaction timeout
// If we get out of the loop successfully, we can successfully
// set the transaction on this puppy.
TxLock txLock = null;
Object deadlocker = miTx;
if (deadlocker == null) deadlocker = Thread.currentThread();
while (getTransaction() != null &&
// And are we trying to enter with another transaction?
!getTransaction().equals(miTx))
{
// Check for a deadlock on every cycle
try
{
if( deadlockDetection == true )
DeadlockDetector.singleton.deadlockDetection(deadlocker, this);
}
catch (Exception e)
{
// We were queued, not any more
if (txLock != null && txLock.isQueued)
{
txLocks.remove(txLock);
txWaitQueue.remove(txLock);
}
throw e;
}
wasScheduled = true;
if (lockMonitor != null) lockMonitor.contending();
// That's no good, only one transaction per context
// Let's put the thread to sleep the transaction demarcation will wake them up
if (trace) log.trace("Transactional contention on context" + id);
// Only queue the lock on the first iteration
if (txLock == null)
txLock = getTxLock(miTx);
if (trace) log.trace("Begin wait on Tx=" + getTransaction());
// And lock the threads on the lock corresponding to the Tx in MI
synchronized (txLock)
{
releaseSync();
try
{
txLock.wait(txTimeout);
}
catch (InterruptedException ignored)
{
intr = true;
}
} // end synchronized(txLock)
this.sync();
if (trace) log.trace("End wait on TxLock=" + getTransaction());
if (isTxExpired(miTx))
{
log.error(Thread.currentThread() + "Saw rolled back tx=" + miTx + " waiting for txLock"
// +" On method: " + mi.getMethod().getName()
// +" txWaitQueue size: " + txWaitQueue.size()
);
if (txLock.isQueued)
{
// Remove the TxLock from the queue because this thread is exiting.
// Don't worry about notifying other threads that share the same transaction.
// They will timeout and throw the below RuntimeException
txLocks.remove(txLock);
txWaitQueue.remove(txLock);
}
else if (getTransaction() != null && getTransaction().equals(miTx))
{
// We're not qu
nextTransaction();
}
if (miTx != null)
{
if( deadlockDetection == true )
DeadlockDetector.singleton.removeWaiting(deadlocker);
}
throw new RuntimeException("Transaction marked for rollback, possibly a timeout");
}
} // end while(tx!=miTx)
// If we get here, this means that we have the txlock
if (!wasScheduled)
{
setTransaction(miTx);
}
return wasScheduled;
}
finally
{
if (intr) Thread.currentThread().interrupt();
}
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInstanceCache.java
public void create() throws Exception
{
getCache().create();
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInstanceCache.java
public void start() throws Exception
{
getCache().start();
}
// in src/main/java/org/jboss/ejb/plugins/MessageDrivenInstanceInterceptor.java
public Object invokeHome(final Invocation mi)
throws Exception
{
throw new Error("Not valid for MessageDriven beans");
}
// in src/main/java/org/jboss/ejb/plugins/MessageDrivenInstanceInterceptor.java
public Object invoke(final Invocation mi)
throws Exception
{
// Get context
MessageDrivenContainer mdc = (MessageDrivenContainer) container;
InstancePool pool = mdc.getInstancePool();
EnterpriseContext ctx = null;
try
{
ctx = pool.get();
}
catch (EJBException e)
{
throw e;
}
catch (Exception e)
{
throw new EJBException("Unable to get an instance from the pool", e);
}
// Set the current security information
ctx.setPrincipal(mi.getPrincipal());
// Use this context
mi.setEnterpriseContext(ctx);
// Set the JACC EnterpriseBean PolicyContextHandler data
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx.getInstance());
if (ejbTimeout.equals(mi.getMethod()))
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_TIMEOUT);
else
AllowedOperationsAssociation.pushInMethodFlag(IN_BUSINESS_METHOD);
// There is no need for synchronization since the instance is always
// fresh also there should never be a tx associated with the instance.
try
{
// Invoke through interceptors
Object obj = getNext().invoke(mi);
return obj;
}
catch (RuntimeException e) // Instance will be GC'ed at MI return
{
mi.setEnterpriseContext(null);
throw e;
}
catch (RemoteException e) // Instance will be GC'ed at MI return
{
mi.setEnterpriseContext(null);
throw e;
}
catch (Error e) // Instance will be GC'ed at MI return
{
mi.setEnterpriseContext(null);
throw e;
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
// Return context
if (mi.getEnterpriseContext() != null)
{
pool.free((EnterpriseContext) mi.getEnterpriseContext());
}
else
{
pool.discard(ctx);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInterceptor.java
public void create() throws Exception
{
// empty
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInterceptor.java
public void start() throws Exception
{
// empty
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInterceptor.java
public Object invokeHome(final Invocation mi) throws Exception
{
// assert mi != null;
return getNext().invokeHome(mi);
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInterceptor.java
public Object invoke(final Invocation mi) throws Exception
{
// assert mi != null;
return getNext().invoke(mi);
}
// in src/main/java/org/jboss/ejb/plugins/EntityInstancePool.java
protected EnterpriseContext create(Object instance)
throws Exception
{
return new EntityEnterpriseContext(instance, getContainer());
}
// in src/main/java/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java
public void create()
throws Exception
{
try
{
ConfigurationMetaData configuration = container.getBeanMetaData().getContainerConfiguration();
commitOption = configuration.getCommitOption();
optionDRefreshRate = configuration.getOptionDRefreshRate();
}
catch(Exception e)
{
log.warn(e.getMessage());
}
}
// in src/main/java/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
Transaction tx = mi.getTransaction();
Object rtn = getNext().invokeHome(mi);
// An anonymous context was sent in, so if it has an id it is a real instance now
if(ctx.getId() != null)
{
// it doesn't need to be read, but it might have been changed from the db already.
ctx.setValid(true);
if(tx != null)
{
BeanLock lock = container.getLockManager().getLock(ctx.getCacheKey());
try
{
lock.schedule(mi);
register(ctx, tx); // Set tx
lock.endInvocation(mi);
}
finally
{
container.getLockManager().removeLockRef(lock.getId());
}
}
}
return rtn;
}
// in src/main/java/org/jboss/ejb/plugins/EntitySynchronizationInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
// We are going to work with the context a lot
EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
// The Tx coming as part of the Method Invocation
Transaction tx = mi.getTransaction();
if(log.isTraceEnabled())
log.trace("invoke called for ctx " + ctx + ", tx=" + tx);
if(!ctx.isValid())
{
container.getPersistenceManager().loadEntity(ctx);
ctx.setValid(true);
}
// mark the context as read only if this is a readonly method and the context
// was not already readonly
boolean didSetReadOnly = false;
if(!ctx.isReadOnly() &&
(container.isReadOnly() ||
container.getBeanMetaData().isMethodReadOnly(mi.getMethod())))
{
ctx.setReadOnly(true);
didSetReadOnly = true;
}
// So we can go on with the invocation
// Invocation with a running Transaction
try
{
if(tx != null && tx.getStatus() != Status.STATUS_NO_TRANSACTION)
{
// readonly does not synchronize, lock or belong with transaction.
boolean isReadOnly = container.isReadOnly();
if(isReadOnly == false)
{
Method method = mi.getMethod();
if(method != null)
isReadOnly = container.getBeanMetaData().isMethodReadOnly(method.getName());
}
try
{
if(isReadOnly == false)
{
// register the wrapper with the transaction monitor (but only
// register once). The transaction demarcation will trigger the
// storage operations
register(ctx, tx);
}
//Invoke down the chain
Object retVal = getNext().invoke(mi);
// Register again as a finder in the middle of a method
// will de-register this entity, and then the rest of the method can
// change fields which will never be stored
if(isReadOnly == false)
{
// register the wrapper with the transaction monitor (but only
// register once). The transaction demarcation will trigger the
// storage operations
register(ctx, tx);
}
// return the return value
return retVal;
}
finally
{
// We were read-only and the context wasn't already synchronized, tidyup the cache
if(isReadOnly && ctx.hasTxSynchronization() == false)
{
switch(commitOption)
{
// Keep instance active, but invalidate state
case ConfigurationMetaData.B_COMMIT_OPTION:
// Invalidate state (there might be other points of entry)
ctx.setValid(false);
break;
// Invalidate everything AND Passivate instance
case ConfigurationMetaData.C_COMMIT_OPTION:
try
{
// FIXME: We cannot passivate here, because previous
// interceptors work with the context, in particular
// the re-entrance interceptor is doing lock counting
// Just remove it from the cache
if(ctx.getId() != null)
container.getInstanceCache().remove(ctx.getId());
}
catch(Exception e)
{
log.debug("Exception releasing context", e);
}
break;
}
}
}
}
else
{
// No tx
try
{
Object result = getNext().invoke(mi);
// Store after each invocation -- not on exception though, or removal
// And skip reads too ("get" methods)
if(ctx.getId() != null && !container.isReadOnly())
{
container.invokeEjbStore(ctx);
container.storeEntity(ctx);
}
return result;
}
catch(Exception e)
{
// Exception - force reload on next call
ctx.setValid(false);
throw e;
}
finally
{
switch(commitOption)
{
// Keep instance active, but invalidate state
case ConfigurationMetaData.B_COMMIT_OPTION:
// Invalidate state (there might be other points of entry)
ctx.setValid(false);
break;
// Invalidate everything AND Passivate instance
case ConfigurationMetaData.C_COMMIT_OPTION:
try
{
// Do not call release if getId() is null. This means that
// the entity has been removed from cache.
// release will schedule a passivation and this removed ctx
// could be put back into the cache!
// This is necessary because we have no lock, we
// don't want to return an instance to the pool that is
// being used
if(ctx.getId() != null)
container.getInstanceCache().remove(ctx.getId());
}
catch(Exception e)
{
log.debug("Exception releasing context", e);
}
break;
}
}
}
}
finally
{
// if we marked the context as read only we need to reset it
if(didSetReadOnly)
{
ctx.setReadOnly(false);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/EntityCreationInterceptor.java
public Object invokeHome(Invocation mi)
throws Exception
{
// Invoke through interceptors
Object retVal = getNext().invokeHome(mi);
// Is the context now with an identity?
// This means that a create method was called, so invoke ejbPostCreate.
EntityEnterpriseContext ctx =
(EntityEnterpriseContext) mi.getEnterpriseContext();
if(ctx != null && ctx.getId() != null)
{
// copy from the context into the mi
// interceptors down the chain look in the mi for the id not the ctx.
mi.setId(ctx.getId());
// invoke down the invoke chain
// the final interceptor in EntityContainer will redirect this
// call to postCreateEntity, which calls ejbPostCreate
getNext().invoke(mi);
// now it's ready and can be scheduled for the synchronization
if(TxUtils.isActive(mi.getTransaction()))
{
GlobalTxEntityMap.NONE.scheduleSync(mi.getTransaction(), ctx);
}
}
return retVal;
}
// in src/main/java/org/jboss/ejb/plugins/EntityCreationInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
// nothing to see here... move along
return getNext().invoke(mi);
}
// in src/main/java/org/jboss/ejb/plugins/CallValidationInterceptor.java
public Object invokeHome(final Invocation mi) throws Exception
{
validateArguments(mi);
Object obj = getNext().invokeHome(mi);
return validateReturnValue(mi, obj);
}
// in src/main/java/org/jboss/ejb/plugins/CallValidationInterceptor.java
public Object invoke(final Invocation mi) throws Exception
{
validateArguments(mi);
Object obj = getNext().invoke(mi);
return validateReturnValue(mi, obj);
}
// in src/main/java/org/jboss/ejb/plugins/SecurityRolesInterceptor.java
public void start() throws Exception
{
super.start();
}
// in src/main/java/org/jboss/ejb/plugins/SecurityRolesInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
// Apply any declarative security checks
checkSecurityAssociation(mi);
Object returnValue = getNext().invokeHome(mi);
return returnValue;
}
// in src/main/java/org/jboss/ejb/plugins/SecurityRolesInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
// Authenticate the subject and apply any declarative security checks
checkSecurityAssociation(mi);
Object returnValue = getNext().invoke(mi);
return returnValue;
}
// in src/main/java/org/jboss/ejb/plugins/SecurityRolesInterceptor.java
private void checkSecurityAssociation(Invocation mi)
throws Exception
{
Principal principal = mi.getPrincipal();
boolean trace = log.isTraceEnabled();
if (realmMapping == null)
{
throw new EJBException("checkSecurityAssociation",
new SecurityException("Role mapping manager has not been set"));
}
// Get the method permissions
InvocationType iface = mi.getType();
Set methodRoles = container.getMethodPermissions(mi.getMethod(), iface);
if (methodRoles == null)
{
String method = mi.getMethod().getName();
String msg = "No method permissions assigned to method=" + method
+ ", interface=" + iface;
log.error(msg);
SecurityException e = new SecurityException(msg);
throw new EJBException("checkSecurityAssociation", e);
}
else if (trace)
{
log.trace("method=" + mi.getMethod() + ", interface=" + iface
+ ", requiredRoles=" + methodRoles);
}
// Check if the caller is allowed to access the method
RunAsIdentity callerRunAsIdentity = SecurityAssociation.peekRunAsIdentity();
if (methodRoles.contains(AnybodyPrincipal.ANYBODY_PRINCIPAL) == false)
{
// The caller is using a the caller identity
if (callerRunAsIdentity == null)
{
// Now actually check if the current caller has one of the required method roles
if (realmMapping.doesUserHaveRole(principal, methodRoles) == false)
{
Set userRoles = realmMapping.getUserRoles(principal);
String method = mi.getMethod().getName();
String msg = "Insufficient method permissions, principal=" + principal
+ ", method=" + method + ", interface=" + iface
+ ", requiredRoles=" + methodRoles + ", principalRoles=" + userRoles;
log.error(msg);
SecurityException e = new SecurityException(msg);
throw new EJBException("checkSecurityAssociation", e);
}
}
// The caller is using a run-as identity
else
{
// Check that the run-as role is in the set of method roles
if (callerRunAsIdentity.doesUserHaveRole(methodRoles) == false)
{
String method = mi.getMethod().getName();
String msg = "Insufficient method permissions, runAsPrincipal=" + callerRunAsIdentity.getName()
+ ", method=" + method + ", interface=" + iface
+ ", requiredRoles=" + methodRoles + ", runAsRoles=" + callerRunAsIdentity.getRunAsRoles();
log.error(msg);
SecurityException e = new SecurityException(msg);
throw new EJBException("checkSecurityAssociation", e);
}
}
}
}
// in src/main/java/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
public void start() throws Exception
{
super.start();
}
// in src/main/java/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
boolean isInvokeMethod = false;
return this.process(mi, isInvokeMethod);
}
// in src/main/java/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
boolean isInvokeMethod = true;
return this.process(mi, isInvokeMethod);
}
// in src/main/java/org/jboss/ejb/plugins/RunAsSecurityInterceptor.java
public Object process(Invocation mi, boolean isInvokeMethod) throws Exception
{
String securityDomain = SecurityConstants.DEFAULT_APPLICATION_POLICY;
if(securityManager != null)
{
securityDomain = securityManager.getSecurityDomain();
}
if (log.isTraceEnabled())
{
log.trace("Bean:"+ container.getServiceName() + " securityDomain="+securityDomain
+ " isInvokeMethod="+ isInvokeMethod);
}
//Establish a security context if one is missing for Run-As push
if(SecurityActions.getSecurityContext() == null)
{
SecurityActions.createAndSetSecurityContext(mi.getPrincipal(),
mi.getCredential(), securityDomain);
}
/* If a run-as role was specified, push it so that any calls made
by this bean will have the runAsRole available for declarative
security checks.
*/
SecurityActions.pushRunAsIdentity(runAsIdentity);
SecurityActions.pushCallerRunAsIdentity(runAsIdentity);
if (log.isTraceEnabled())
{
log.trace("Security Context = " + SecurityActions.trace(SecurityActions.getSecurityContext()));
}
try
{
if(isInvokeMethod)
return getNext().invoke(mi);
else
return getNext().invokeHome(mi);
}
finally
{
SecurityActions.popRunAsIdentity();
SecurityActions.popCallerRunAsIdentity();
}
}
// in src/main/java/org/jboss/ejb/plugins/NoPassivationCachePolicy.java
public void create() throws Exception
{
m_map = new HashMap();
}
// in src/main/java/org/jboss/ejb/plugins/NoPassivationCachePolicy.java
public void start() throws Exception
{
}
// in src/main/java/org/jboss/ejb/plugins/AbstractTxInterceptor.java
public void create() throws Exception
{
super.create();
tm = getContainer().getTransactionManager();
}
// in src/main/java/org/jboss/ejb/plugins/AbstractTxInterceptor.java
protected Object invokeNext(Invocation invocation, boolean inheritedTx)
throws Exception
{
InvocationType type = invocation.getType();
try
{
if (type == InvocationType.REMOTE || type == InvocationType.LOCAL || type == InvocationType.SERVICE_ENDPOINT)
{
// register the Timer with the transaction
if (ejbTimeout.equals(invocation.getMethod()))
registerTimer(invocation);
return getNext().invoke(invocation);
}
else
{
return getNext().invokeHome(invocation);
}
}
catch (Throwable e)
{
// if this is an ApplicationException, just rethrow it
if (e instanceof Exception &&
!(e instanceof RuntimeException || e instanceof RemoteException))
{
throw (Exception) e;
}
// attempt to rollback the transaction
Transaction tx = invocation.getTransaction();
if (tx == null)
{
// Look for a hanging active user transaction that we should mark rollback
try
{
tx = tm.getTransaction();
if (TxUtils.isActive(tx) == false)
tx = null;
}
catch (Exception ex)
{
log.warn("Unable to determine transaction context", ex);
}
}
if (tx != null)
{
try
{
tx.setRollbackOnly();
}
catch (SystemException ex)
{
log.error("SystemException while setting transaction " +
"for rollback only", ex);
}
catch (IllegalStateException ex)
{
log.error("IllegalStateException while setting transaction " +
"for rollback only", ex);
}
}
// is this a local invocation
boolean isLocal =
type == InvocationType.LOCAL ||
type == InvocationType.LOCALHOME;
// if this transaction was NOT inherited from the caller we simply
// rethrow the exception, and LogInterceptor will handle
// all exception conversions.
if (!inheritedTx)
{
if (e instanceof Exception)
{
throw (Exception) e;
}
if (e instanceof Error)
{
throw (Error) e;
}
// we have some funky throwable, wrap it
if (isLocal)
{
String msg = formatException("Unexpected Throwable", e);
throw new EJBException(msg);
}
else
{
ServerException ex = new ServerException("Unexpected Throwable");
ex.detail = e;
throw ex;
}
}
// to be nice we coerce the execption to an interface friendly type
// before wrapping it with a transaction rolled back exception
Throwable cause;
if (e instanceof NoSuchEntityException)
{
NoSuchEntityException nsee = (NoSuchEntityException) e;
if (isLocal)
{
cause = new NoSuchObjectLocalException(nsee.getMessage(),
nsee.getCausedByException());
}
else
{
cause = new NoSuchObjectException(nsee.getMessage());
// set the detil of the exception
((NoSuchObjectException) cause).detail =
nsee.getCausedByException();
}
}
else
{
if (isLocal)
{
// local transaction rolled back exception can only wrap
// an exception so we create an EJBException for the cause
if (e instanceof Exception)
{
cause = e;
}
else if (e instanceof Error)
{
String msg = formatException("Unexpected Error", e);
cause = new EJBException(msg);
}
else
{
String msg = formatException("Unexpected Throwable", e);
cause = new EJBException(msg);
}
}
else
{
// remote transaction rolled back exception can wrap
// any throwable so we are ok
cause = e;
}
}
// We inherited tx: Tell caller we marked for rollback only.
if (isLocal)
{
if (cause instanceof TransactionRolledbackLocalException)
{
throw (TransactionRolledbackLocalException) cause;
}
else
{
throw new TransactionRolledbackLocalException(cause.getMessage(),
(Exception) cause);
}
}
else
{
if (cause instanceof TransactionRolledbackException)
{
throw (TransactionRolledbackException) cause;
}
else
{
TransactionRolledbackException ex =
new TransactionRolledbackException(cause.getMessage());
ex.detail = cause;
throw ex;
}
}
}
}
// in src/main/java/org/jboss/ejb/plugins/EntityReentranceInterceptor.java
protected boolean isTxExpired(Transaction miTx) throws Exception
{
return TxUtils.isRollback(miTx);
}
// in src/main/java/org/jboss/ejb/plugins/EntityReentranceInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
// We are going to work with the context a lot
EntityEnterpriseContext ctx = (EntityEnterpriseContext) mi.getEnterpriseContext();
boolean nonReentrant = !(reentrant || isReentrantMethod(mi));
// Not a reentrant method like getPrimaryKey
NonReentrantLock methodLock = ctx.getMethodLock();
Transaction miTx = ctx.getTransaction();
boolean locked = false;
try
{
while (!locked)
{
if (methodLock.attempt(5000, miTx, nonReentrant))
{
locked = true;
}
else
{
if (isTxExpired(miTx))
{
log.error("Saw rolled back tx=" + miTx);
throw new RuntimeException("Transaction marked for rollback, possibly a timeout");
}
}
}
}
catch (NonReentrantLock.ReentranceException re)
{
if (mi.getType() == InvocationType.REMOTE)
{
throw new RemoteException("Reentrant method call detected: "
+ container.getBeanMetaData().getEjbName() + " "
+ ctx.getId().toString());
}
else
{
throw new EJBException("Reentrant method call detected: "
+ container.getBeanMetaData().getEjbName() + " "
+ ctx.getId().toString());
}
}
try
{
ctx.lock();
return getNext().invoke(mi);
}
finally
{
ctx.unlock();
methodLock.release(nonReentrant);
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public void create()
throws Exception
{
if(con.getHomeClass() != null)
{
Method[] methods = con.getHomeClass().getMethods();
createMethodCache(methods);
}
if(con.getLocalHomeClass() != null)
{
Method[] methods = con.getLocalHomeClass().getMethods();
createMethodCache(methods);
}
insertAfterEjbPostCreate = con.getBeanMetaData().getContainerConfiguration().isInsertAfterEjbPostCreate();
store.create();
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public Object createBeanClassInstance() throws Exception
{
return store.createBeanClassInstance();
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public void start()
throws Exception
{
store.start();
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public void createEntity(Method m, Object[] args, EntityEnterpriseContext ctx)
throws Exception
{
// Deligate initialization of bean to persistence store
store.initEntity(ctx);
// Call ejbCreate on the target bean
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_CREATE);
Method createMethod = (Method) createMethods.get(m);
createMethod.invoke(ctx.getInstance(), args);
}
catch(IllegalAccessException e)
{
// Throw this as a bean exception...(?)
throw new EJBException(e);
}
catch(InvocationTargetException ite)
{
Throwable e = ite.getTargetException();
if(e instanceof EJBException)
{
// Rethrow exception
throw (EJBException) e;
}
else if(e instanceof RuntimeException)
{
// Wrap runtime exceptions
throw new EJBException((Exception) e);
}
else if(e instanceof Exception)
{
// Remote, Create, or custom app. exception
throw (Exception) e;
}
else
{
throw (Error) e;
}
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
// if insertAfterEjbPostCreate == true, this will INSERT entity
// otherwise, primary key is extracted from the context and returned
Object id;
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_CREATE);
id = store.createEntity(m, args, ctx);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
// Set the key on the target context
ctx.setId(id);
// Create a new CacheKey
Object cacheKey = ((EntityCache) con.getInstanceCache()).createCacheKey(id);
// Give it to the context
ctx.setCacheKey(cacheKey);
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public void postCreateEntity(Method m, Object[] args, EntityEnterpriseContext ctx)
throws Exception
{
// this call should go first as it sets up relationships
// for fk fields mapped to pk fields
store.postCreateEntity(m, args, ctx);
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_POST_CREATE);
Method postCreateMethod = (Method) postCreateMethods.get(m);
postCreateMethod.invoke(ctx.getInstance(), args);
if(insertAfterEjbPostCreate)
{
store.createEntity(m, args, ctx);
}
}
catch(IllegalAccessException e)
{
// Throw this as a bean exception...(?)
throw new EJBException(e);
}
catch(InvocationTargetException ite)
{
Throwable e = ite.getTargetException();
if(e instanceof EJBException)
{
// Rethrow exception
throw (EJBException) e;
}
else if(e instanceof RuntimeException)
{
// Wrap runtime exceptions
throw new EJBException((Exception) e);
}
else if(e instanceof Exception)
{
// Remote, Create, or custom app. exception
throw (Exception) e;
}
else
{
throw (Error) e;
}
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public Object findEntity(Method finderMethod,
Object[] args,
EntityEnterpriseContext ctx,
GenericEntityObjectFactory factory)
throws Exception
{
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_FIND);
return store.findEntity(finderMethod, args, ctx, factory);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public Collection findEntities(Method finderMethod,
Object[] args,
EntityEnterpriseContext ctx,
GenericEntityObjectFactory factory)
throws Exception
{
try
{
// return the finderResults so that the invoker layer can extend this back
// giving the client an OO 'cursor'
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_FIND);
return store.findEntities(finderMethod, args, ctx, factory);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public boolean isStoreRequired(EntityEnterpriseContext ctx) throws Exception
{
return store.isStoreRequired(ctx);
}
// in src/main/java/org/jboss/ejb/plugins/CMPPersistenceManager.java
public boolean isModified(EntityEnterpriseContext ctx) throws Exception
{
return store.isModified(ctx);
}
// in src/main/java/org/jboss/ejb/plugins/SingletonStatelessSessionInstancePool.java
public synchronized EnterpriseContext get()
throws Exception
{
boolean intr = false;
try
{
// Wait while someone else is using it
while(inUse && isSynchronized)
{
try { this.wait(); } catch (InterruptedException e) { intr = true; }
}
// Create if not already created (or it has been discarded)
if (ctx == null)
{
try
{
ctx = create(getContainer().createBeanClassInstance());
} catch (InstantiationException e)
{
throw new EJBException("Could not instantiate bean", e);
} catch (IllegalAccessException e)
{
throw new EJBException("Could not instantiate bean", e);
}
}
else
{
}
// Lock and return instance
inUse = true;
return ctx;
}
finally
{
if (intr) Thread.currentThread().interrupt();
}
}
// in src/main/java/org/jboss/ejb/plugins/SingletonStatelessSessionInstancePool.java
public void add()
throws Exception
{
// Empty
}
// in src/main/java/org/jboss/ejb/plugins/SingletonStatelessSessionInstancePool.java
protected EnterpriseContext create(Object instance)
throws Exception
{
// The instance is created by the caller and is a newInstance();
return new StatelessSessionEnterpriseContext(instance, getContainer());
}
// in src/main/java/org/jboss/ejb/plugins/StatelessSessionInstanceInterceptor.java
public Object invokeHome(final Invocation mi) throws Exception
{
InstancePool pool = container.getInstancePool();
StatelessSessionEnterpriseContext ctx = null;
try
{
// Acquire an instance in case the ejbCreate throws a CreateException
ctx = (StatelessSessionEnterpriseContext) pool.get();
mi.setEnterpriseContext(ctx);
// Dispatch the method to the container
return getNext().invokeHome(mi);
}
finally
{
mi.setEnterpriseContext(null);
// If an instance was created, return it to the pool
if( ctx != null )
pool.free(ctx);
}
}
// in src/main/java/org/jboss/ejb/plugins/StatelessSessionInstanceInterceptor.java
public Object invoke(final Invocation mi) throws Exception
{
// Get context
InstancePool pool = container.getInstancePool();
StatelessSessionEnterpriseContext ctx = null;
try
{
ctx = (StatelessSessionEnterpriseContext) pool.get();
}
catch (EJBException e)
{
throw e;
}
catch (RemoteException e)
{
throw e;
}
catch (Exception e)
{
InvocationType type = mi.getType();
boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
if (isLocal)
throw new EJBException("Unable to get an instance from the pool", e);
else
throw new RemoteException("Unable to get an intance from the pool", e);
}
// Set the current security information
ctx.setPrincipal(mi.getPrincipal());
// Set the JACC EnterpriseBean PolicyContextHandler data
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx.getInstance());
// Use this context
mi.setEnterpriseContext(ctx);
// JAXRPC/JAXWS message context
Object msgContext = mi.getValue(InvocationKey.SOAP_MESSAGE_CONTEXT);
// Timer invocation
if (ejbTimeout.equals(mi.getMethod()))
{
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_TIMEOUT);
}
// Service Endpoint invocation
else if (msgContext != null)
{
if (msgContext instanceof javax.xml.rpc.handler.MessageContext)
ctx.setMessageContext((javax.xml.rpc.handler.MessageContext)msgContext);
AllowedOperationsAssociation.pushInMethodFlag(IN_SERVICE_ENDPOINT_METHOD);
}
// Business Method Invocation
else
{
AllowedOperationsAssociation.pushInMethodFlag(IN_BUSINESS_METHOD);
}
// There is no need for synchronization since the instance is always fresh also there should
// never be a tx associated with the instance.
try
{
Object obj = getNext().invoke(mi);
return obj;
}
catch (RuntimeException e) // Instance will be GC'ed at MI return
{
mi.setEnterpriseContext(null);
throw e;
}
catch (RemoteException e) // Instance will be GC'ed at MI return
{
mi.setEnterpriseContext(null);
throw e;
}
catch (Error e) // Instance will be GC'ed at MI return
{
mi.setEnterpriseContext(null);
throw e;
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
// Return context
if (mi.getEnterpriseContext() != null)
{
pool.free(((EnterpriseContext) mi.getEnterpriseContext()));
}
else
{
pool.discard(ctx);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
protected void createService() throws Exception
{
// Initialize the dataStore
String ejbName = con.getBeanMetaData().getEjbName();
// Get the system data directory
File dir = new File(ServerConfigLocator.locate().getServerDataLocation().toURI());
//
// jason: may have to use a generated token from container config
// to determine a unique name for this config for the given
// entity name. it must persist through restarts though...
//
// Setup the reference to the entity data store directory
dir = new File(dir, storeDirName);
dir = new File(dir, ejbName);
storeDir = dir;
log.debug("Storing entity state for '" + ejbName + "' in: " + storeDir);
// if the directory does not exist then try to create it
if (!storeDir.exists()) {
if (!storeDir.mkdirs()) {
throw new IOException("Failed to create directory: " + storeDir);
}
}
// make sure we have a directory
if (!storeDir.isDirectory()) {
throw new IOException("File exists where directory expected: " + storeDir);
}
// make sure we can read and write to it
if (!storeDir.canWrite() || !storeDir.canRead()) {
throw new IOException("Directory must be readable and writable: " + storeDir);
}
// Get the ID field
idField = con.getBeanClass().getField("id");
log.debug("Using id field: " + idField);
// Lookup the isModified method if it exists
try
{
isModified = con.getBeanClass().getMethod("isModified", new Class[0]);
if (!isModified.getReturnType().equals(Boolean.TYPE)) {
isModified = null; // Has to have "boolean" as return type!
log.warn("Found isModified method, but return type is not boolean; ignoring");
}
else {
log.debug("Using isModified method: " + isModified);
}
}
catch (NoSuchMethodException ignored) {}
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
protected void destroyService() throws Exception
{
storeDir.delete();
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
public Object createBeanClassInstance() throws Exception
{
return con.getBeanClass().newInstance();
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
public Object createEntity(final Method m,
final Object[] args,
final EntityEnterpriseContext ctx)
throws Exception
{
try {
Object id = idField.get(ctx.getInstance());
// Check exist
if (getFile(id).exists())
throw new DuplicateKeyException("Already exists: "+id);
// Store to file
storeEntity(id, ctx.getInstance());
return id;
}
catch (IllegalAccessException e)
{
throw new CreateException("Could not create entity: "+e);
}
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
public Object postCreateEntity(final Method m,
final Object[] args,
final EntityEnterpriseContext ctx)
throws Exception
{
return null;
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
public boolean isStoreRequired(final EntityEnterpriseContext ctx) throws Exception
{
if (isModified == null)
{
return true;
}
Boolean modified = (Boolean) isModified.invoke(ctx.getInstance(), new Object[0]);
return modified.booleanValue();
}
// in src/main/java/org/jboss/ejb/plugins/CMPFilePersistenceManager.java
public boolean isModified(EntityEnterpriseContext ctx) throws Exception
{
return isStoreRequired(ctx);
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionInstanceCache.java
protected EnterpriseContext acquireContext() throws Exception
{
return m_container.getInstancePool().get();
}
// in src/main/java/org/jboss/ejb/plugins/MetricsInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
long begin = System.currentTimeMillis();
try
{
return super.invokeHome(mi);
}
finally
{
if (mi.getMethod() != null && publisher.isAlive())
{
addEntry(mi, begin, System.currentTimeMillis());
}
}
}
// in src/main/java/org/jboss/ejb/plugins/MetricsInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
long begin = System.currentTimeMillis();
try
{
return super.invoke(mi);
}
finally
{
if (mi.getMethod() != null && publisher.isAlive())
{
addEntry(mi, begin, System.currentTimeMillis());
}
}
}
// in src/main/java/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
public void create() throws Exception
{
BeanMetaData metaData = container.getBeanMetaData();
localJndiName = metaData.getLocalJndiName();
}
// in src/main/java/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
public void start()
throws Exception
{
BeanMetaData metaData = container.getBeanMetaData();
EJBProxyFactoryContainer invokerContainer =
(EJBProxyFactoryContainer) container;
localHomeClass = invokerContainer.getLocalHomeClass();
localClass = invokerContainer.getLocalClass();
if(localHomeClass == null || localClass == null)
{
log.debug(metaData.getEjbName()
+
" cannot be Bound, doesn't " +
"have local and local home interfaces");
return;
}
// this is faster than newProxyInstance
Class[] intfs = {localClass};
Class proxyClass = Proxy.getProxyClass(ClassLoaderAction.UTIL.get(localClass), intfs);
final Class[] constructorParams =
{InvocationHandler.class};
proxyClassConstructor = proxyClass.getConstructor(constructorParams);
Context iniCtx = new InitialContext();
String beanName = metaData.getEjbName();
// Set the transaction manager and transaction propagation
// context factory of the GenericProxy class
transactionManager =
(TransactionManager) iniCtx.lookup("java:/TransactionManager");
// Create method mappings for container invoker
Method[] methods = localClass.getMethods();
beanMethodInvokerMap = new HashMap();
for(int i = 0; i < methods.length; i++)
{
long hash = MarshalledInvocation.calculateHash(methods[i]);
beanMethodInvokerMap.put(new Long(hash), methods[i]);
}
methods = localHomeClass.getMethods();
homeMethodInvokerMap = new HashMap();
for(int i = 0; i < methods.length; i++)
{
long hash = MarshalledInvocation.calculateHash(methods[i]);
homeMethodInvokerMap.put(new Long(hash), methods[i]);
}
// bind that referance to my name
Util.rebind(iniCtx, localJndiName, getEJBLocalHome());
invokerMap.put(localJndiName, this);
log.info("Bound EJB LocalHome '" + beanName + "' to jndi '" + localJndiName + "'");
}
// in src/main/java/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
public Object invokeHome(Method m, Object[] args) throws Exception
{
// Set the right context classloader
ClassLoader oldCl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = !oldCl.equals(container.getClassLoader());
if(setCl)
{
TCLAction.UTIL.setContextClassLoader(container.getClassLoader());
}
container.pushENC();
SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
try
{
LocalEJBInvocation invocation = new LocalEJBInvocation(null,
m,
args,
getTransaction(),
sa.getPrincipal(),
sa.getCredential());
invocation.setType(InvocationType.LOCALHOME);
return container.invoke(invocation);
}
catch(AccessException ae)
{
log.trace(ae);
throw new AccessLocalException(ae.getMessage(), ae);
}
catch(NoSuchObjectException nsoe)
{
throw new NoSuchObjectLocalException(nsoe.getMessage(), nsoe);
}
catch(TransactionRequiredException tre)
{
throw new TransactionRequiredLocalException(tre.getMessage());
}
catch(TransactionRolledbackException trbe)
{
throw new TransactionRolledbackLocalException(trbe.getMessage(), trbe);
}
finally
{
container.popENC();
if(setCl)
{
TCLAction.UTIL.setContextClassLoader(oldCl);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/local/BaseLocalProxyFactory.java
public Object invoke(Object id, Method m, Object[] args)
throws Exception
{
// Set the right context classloader
ClassLoader oldCl = TCLAction.UTIL.getContextClassLoader();
boolean setCl = !oldCl.equals(container.getClassLoader());
if(setCl)
{
TCLAction.UTIL.setContextClassLoader(container.getClassLoader());
}
container.pushENC();
SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
try
{
LocalEJBInvocation invocation = new LocalEJBInvocation(id,
m,
args,
getTransaction(),
sa.getPrincipal(),
sa.getCredential());
invocation.setType(InvocationType.LOCAL);
return container.invoke(invocation);
}
catch(AccessException ae)
{
log.trace(ae);
throw new AccessLocalException(ae.getMessage(), ae);
}
catch(NoSuchObjectException nsoe)
{
throw new NoSuchObjectLocalException(nsoe.getMessage(), nsoe);
}
catch(TransactionRequiredException tre)
{
throw new TransactionRequiredLocalException(tre.getMessage());
}
catch(TransactionRolledbackException trbe)
{
throw new TransactionRolledbackLocalException(trbe.getMessage(), trbe);
}
finally
{
container.popENC();
if(setCl)
{
TCLAction.UTIL.setContextClassLoader(oldCl);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/RelationInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
if(!(mi instanceof CMRInvocation))
{
return getNext().invoke(mi);
}
org.jboss.ejb.plugins.cmp.jdbc.bridge.CMRMessage msg = ((CMRInvocation)mi).getCmrMessage();
// We are going to work with the context a lot
EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
JDBCCMRFieldBridge2 cmrField = (JDBCCMRFieldBridge2)mi.getArguments()[0];
if(org.jboss.ejb.plugins.cmp.jdbc.bridge.CMRMessage.ADD_RELATION == msg)
{
Object relatedId = mi.getArguments()[1];
if(log.isTraceEnabled())
{
log.trace("Add relation: field=" + cmrField.getFieldName() +
" id=" + ctx.getId() +
" relatedId=" + relatedId);
}
cmrField.addRelatedId(ctx, relatedId);
}
else if(org.jboss.ejb.plugins.cmp.jdbc.bridge.CMRMessage.REMOVE_RELATION == msg)
{
// call removeRelation
Object relatedId = mi.getArguments()[1];
if(log.isTraceEnabled())
{
log.trace("Remove relation: field=" + cmrField.getFieldName() +
" id=" + ctx.getId() +
" relatedId=" + relatedId);
}
cmrField.removeRelatedId(ctx, relatedId);
}
else
{
// this should not be possible we are using a type safe enum
throw new EJBException("Unknown cmp2.0-relationship-message=" + msg);
}
return null;
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/PartitionedTableCache.java
public void lockForUpdate(Transaction tx, Object pk) throws Exception
{
final int i = getPartitionIndex(pk);
partitions[i].lockForUpdate(tx, pk);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/PartitionedTableCache.java
public void releaseLock(Transaction tx, Object pk) throws Exception
{
final int i = getPartitionIndex(pk);
partitions[i].releaseLock(tx, pk);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/EntityTable.java
public void stop() throws Exception
{
if(cacheInvalidator != null)
{
cacheInvalidator.unregister();
}
if(cacheName != null)
{
serviceController.stop(cacheName);
serviceController.destroy(cacheName);
serviceController.remove(cacheName);
}
serviceController = null;
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/Cache.java
public void lockForUpdate(Transaction tx, Object pk) throws Exception
{
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/Cache.java
public void releaseLock(Transaction tx, Object pk) throws Exception
{
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/TableCache.java
public void lockForUpdate(Transaction tx, Object pk) throws Exception
{
CachedRow row = (CachedRow) rowsById.get(pk);
if(row != null)
{
if(row.locker != null && !tx.equals(row.locker))
{
throw new Exception("lock acquisition rejected for " +
tx +
", the entry is locked for update by " + row.locker + ", id=" + pk);
}
row.locker = tx;
}
// else?!
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/schema/TableCache.java
public void releaseLock(Transaction tx, Object pk) throws Exception
{
CachedRow row = (CachedRow) rowsById.get(pk);
if(row != null)
{
if(!tx.equals(row.locker))
{
throw new Exception("rejected to release lock for " +
tx +
", the entry is locked for update by " + row.locker + ", id=" + pk);
}
row.locker = null;
}
// else?!
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
public void create() throws Exception
{
HashMap managersMap = (HashMap)getApplicationData(CREATED_MANAGERS);
if(managersMap == null)
{
managersMap = new HashMap();
putApplicationData(CREATED_MANAGERS, managersMap);
}
managersMap.put(container.getBeanMetaData().getEjbName(), this);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
public void start() throws Exception
{
initStoreManager();
HashMap managersMap = (HashMap)getApplicationData(CREATED_MANAGERS);
Catalog catalog = getCatalog();
if(catalog.getEntityCount() == managersMap.size() && catalog.getEJBNames().equals(managersMap.keySet()))
{
// Make a copy of the managers (for safty)
List managers = new ArrayList(managersMap.values());
// Start Phase 2: resolve relationships
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager2 manager = (JDBCStoreManager2)managers.get(i);
manager.resolveRelationships();
}
// Start Phase 3: init cmr loaders
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager2 manager = (JDBCStoreManager2)managers.get(i);
manager.startEntity();
}
// Start Phase 4: create tables and compile queries
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager2 manager = (JDBCStoreManager2)managers.get(i);
manager.startStoreManager();
}
// add foreign key constraints
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager2 manager = (JDBCStoreManager2)managers.get(i);
manager.startCmd.addForeignKeyConstraints();
}
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
public Object createBeanClassInstance() throws Exception
{
return instanceFactory.newInstance();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
public boolean isModified(EntityEnterpriseContext instance) throws Exception
{
return entityBridge.isModified(instance);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
protected void initStoreManager() throws Exception
{
if(log.isDebugEnabled())
{
log.debug("Initializing CMP plugin for " + container.getBeanMetaData().getEjbName());
}
metaData = loadJDBCEntityMetaData();
// setup the type factory, which is used to map java types to sql types.
typeFactory = new JDBCTypeFactory(metaData.getTypeMapping(),
metaData.getJDBCApplication().getValueClasses(),
metaData.getJDBCApplication().getUserTypeMappings()
);
entityBridge = new JDBCEntityBridge2(this, metaData);
entityBridge.init();
Catalog catalog = getCatalog();
catalog.addEntity(entityBridge);
stop = new JDBCStopCommand(this);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
private void resolveRelationships() throws Exception
{
entityBridge.resolveRelationships();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/JDBCStoreManager2.java
protected void startStoreManager() throws Exception
{
queryFactory = new QueryFactory(entityBridge);
queryFactory.init();
instanceFactory = new InstanceFactory(this, entityBridge);
startCmd = new JDBCStartCommand(this);
startCmd.execute();
final JDBCEntityCommandMetaData entityCommand = getMetaData().getEntityCommand();
if(entityCommand == null || "default".equals(entityCommand.getCommandName()))
{
createCmd = new ApplicationPkCreateCommand();
}
else
{
final Class cmdClass = entityCommand.getCommandClass();
if(cmdClass == null)
{
throw new DeploymentException(
"entity-command class name is not specified for entity " + entityBridge.getEntityName()
);
}
try
{
createCmd = (CreateCommand)cmdClass.newInstance();
}
catch(ClassCastException cce)
{
throw new DeploymentException("Entity command " + cmdClass + " does not implement " + CreateCommand.class);
}
}
createCmd.init(this);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/InstanceFactory.java
public Object newInstance() throws Exception
{
EntityBridgeInvocationHandler handler = new EntityBridgeInvocationHandler(fieldMap, selectorMap, beanClass);
return beanProxyConstructor.newInstance(new Object[]{handler});
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/bridge/EJBSelectBridge.java
public Object invoke(EntityEnterpriseContext instance, Method method, Object[] args)
throws Exception
{
Transaction tx = (instance != null ? instance.getTransaction() : tm.getTransaction());
if(syncBeforeSelect)
{
EntityContainer.synchronizeEntitiesWithinTransaction(tx);
}
return execute(args);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc2/bridge/JDBCEntityBridge2.java
public void stop() throws Exception
{
table.stop();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCRelationInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
if(!(mi instanceof CMRInvocation))
return getNext().invoke(mi);
CMRMessage relationshipMessage = ((CMRInvocation)mi).getCmrMessage();
if(relationshipMessage == null)
{
// Not a relationship message. Invoke down the chain
return getNext().invoke(mi);
}
// We are going to work with the context a lot
EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
JDBCCMRFieldBridge cmrField = (JDBCCMRFieldBridge)mi.getArguments()[0];
if(CMRMessage.GET_RELATED_ID == relationshipMessage)
{
// call getRelateId
if(log.isTraceEnabled())
{
log.trace("Getting related id: field=" + cmrField.getFieldName() + " id=" + ctx.getId());
}
return cmrField.getRelatedId(ctx);
}
else if(CMRMessage.ADD_RELATION == relationshipMessage)
{
// call addRelation
Object relatedId = mi.getArguments()[1];
if(log.isTraceEnabled())
{
log.trace("Add relation: field=" + cmrField.getFieldName() +
" id=" + ctx.getId() +
" relatedId=" + relatedId);
}
cmrField.addRelation(ctx, relatedId);
return null;
}
else if(CMRMessage.REMOVE_RELATION == relationshipMessage)
{
// call removeRelation
Object relatedId = mi.getArguments()[1];
if(log.isTraceEnabled())
{
log.trace("Remove relation: field=" + cmrField.getFieldName() +
" id=" + ctx.getId() +
" relatedId=" + relatedId);
}
cmrField.removeRelation(ctx, relatedId);
return null;
}
else if(CMRMessage.SCHEDULE_FOR_CASCADE_DELETE == relationshipMessage)
{
JDBCEntityBridge entity = (JDBCEntityBridge)cmrField.getEntity();
entity.scheduleForCascadeDelete(ctx);
return null;
}
else if(CMRMessage.SCHEDULE_FOR_BATCH_CASCADE_DELETE == relationshipMessage)
{
JDBCEntityBridge entity = (JDBCEntityBridge)cmrField.getEntity();
entity.scheduleForBatchCascadeDelete(ctx);
return null;
}
else
{
// this should not be possible we are using a type safe enum
throw new EJBException("Unknown cmp2.0-relationship-message=" +
relationshipMessage);
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/metadata/MetaDataLibrary.java
public void startService() throws Exception
{
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL stdJDBCUrl = classLoader.getResource("standardjbosscmp-jdbc.xml");
if(stdJDBCUrl == null)
{
throw new DeploymentException("No standardjbosscmp-jdbc.xml found");
}
boolean debug = log.isDebugEnabled();
if(debug)
{
log.debug("Loading standardjbosscmp-jdbc.xml : " + stdJDBCUrl.toString());
}
Element stdJDBCElement = XmlFileLoader.getDocument(stdJDBCUrl, true).getDocumentElement();
Element typeMaps = MetaData.getOptionalChild(stdJDBCElement, "type-mappings");
if(typeMaps != null)
{
for(Iterator i = MetaData.getChildrenByTagName(typeMaps, "type-mapping"); i.hasNext();)
{
Element typeMappingElement = (Element)i.next();
JDBCTypeMappingMetaData typeMapping = new JDBCTypeMappingMetaData(typeMappingElement);
typeMappings.put(typeMapping.getName(), typeMapping);
log.debug("added type-mapping: " + typeMapping.getName());
}
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/metadata/MetaDataLibrary.java
public void stopService() throws Exception
{
typeMappings.clear();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/metadata/DataSourceMetaData.java
public JDBCTypeMappingMetaData getTypeMappingMetaData() throws Exception
{
return (JDBCTypeMappingMetaData)server.invoke(
metadataLibrary,
"findTypeMappingMetaData",
new Object[]{typeMapping},
new String[]{String.class.getName()}
);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/EJBQLToSQL92Compiler.java
public void compileEJBQL(String ejbql, Class returnType, Class[] parameterTypes, JDBCQueryMetaData metadata)
throws Exception
{
// reset all state variables
reset();
// set input arguemts
this.returnType = returnType;
this.parameterTypes = parameterTypes;
this.readAhead = metadata.getReadAhead();
// get the parser
EJBQLParser parser = new EJBQLParser(new StringReader(""));
try
{
// parse the ejbql into an abstract sytax tree
ASTEJBQL ejbqlNode = parser.parse(catalog, parameterTypes, ejbql);
// translate to sql
sql = ejbqlNode.jjtAccept(this, new StringBuffer()).toString();
}
catch(Exception e)
{
// if there is a problem reset the state before exiting
reset();
throw e;
}
catch(Error e)
{
// lame javacc lexer throws Errors
reset();
throw e;
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/EJBQLToSQL92Compiler.java
public void compileJBossQL(String ejbql, Class returnType, Class[] parameterTypes, JDBCQueryMetaData metadata)
throws Exception
{
// reset all state variables
reset();
// set input arguemts
this.returnType = returnType;
this.parameterTypes = parameterTypes;
this.readAhead = metadata.getReadAhead();
// get the parser
JBossQLParser parser = new JBossQLParser(new StringReader(""));
try
{
// parse the ejbql into an abstract sytax tree
ASTEJBQL ejbqlNode = parser.parse(catalog, parameterTypes, ejbql);
// translate to sql
sql = ejbqlNode.jjtAccept(this, new StringBuffer()).toString();
if(log.isTraceEnabled())
{
log.trace("ejbql: " + ejbql);
log.trace("sql: " + sql);
}
}
catch(Exception e)
{
// if there is a problem reset the state before exiting
reset();
throw e;
}
catch(Error e)
{
// lame javacc lexer throws Errors
reset();
throw e;
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCCreateBeanClassInstanceCommand.java
public Object execute() throws Exception
{
EntityBridgeInvocationHandler handler = new EntityBridgeInvocationHandler(fieldMap, selectorMap, beanClass);
return beanProxyConstructor.newInstance(new Object[]{handler});
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCStoreManager.java
public void create() throws Exception
{
// Store a reference to this manager in an application level hashtable.
// This way in the start method other managers will be able to know
// the other managers.
HashMap managersMap = (HashMap)getApplicationData(CREATED_MANAGERS);
if(managersMap == null)
{
managersMap = new HashMap();
putApplicationData(CREATED_MANAGERS, managersMap);
}
managersMap.put(container.getBeanMetaData().getEjbName(), this);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCStoreManager.java
public void start() throws Exception
{
//
//
// Start Phase 1: create bridge and commands but
// don't access other entities
initStoreManager();
// If all managers have been started (this is the last manager),
// complete the other two phases of startup.
Catalog catalog = getCatalog();
HashMap managersMap = (HashMap)getApplicationData(CREATED_MANAGERS);
if(catalog.getEntityCount() == managersMap.size()
&& catalog.getEJBNames().equals(managersMap.keySet()))
{
// Make a copy of the managers (for safty)
ArrayList managers = new ArrayList(managersMap.values());
//
//
// Start Phase 2: resolve relationships
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager manager = (JDBCStoreManager)managers.get(i);
manager.resolveRelationships();
}
//
//
// Start Phase 3: create tables and compile queries
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager manager = (JDBCStoreManager)managers.get(i);
manager.startStoreManager();
}
// add foreign key constraints
for(int i = 0; i < managers.size(); ++i)
{
JDBCStoreManager manager = (JDBCStoreManager)managers.get(i);
manager.startCommand.addForeignKeyConstraints();
}
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCStoreManager.java
private void initStoreManager() throws Exception
{
if(log.isDebugEnabled())
log.debug("Initializing CMP plugin for " + container.getBeanMetaData().getEjbName());
// get the transaction manager
tm = container.getTransactionManager();
// initializes the generic data containers
initApplicationDataMap();
// load the metadata for this entity
metaData = loadJDBCEntityMetaData();
// setup the type factory, which is used to map java types to sql types.
typeFactory = new JDBCTypeFactory(
metaData.getTypeMapping(),
metaData.getJDBCApplication().getValueClasses(),
metaData.getJDBCApplication().getUserTypeMappings()
);
// create the bridge between java land and this engine (sql land)
entityBridge = new JDBCEntityBridge(metaData, this);
entityBridge.init();
// add the entity bridge to the catalog
Catalog catalog = getCatalog();
if(catalog == null)
{
catalog = new Catalog();
putApplicationData(CATALOG, catalog);
}
catalog.addEntity(entityBridge);
// create the read ahead cache
readAheadCache = new ReadAheadCache(this);
readAheadCache.create();
// Set up Commands
commandFactory = new JDBCCommandFactory(this);
// Execute the init command
initCommand = commandFactory.createInitCommand();
initCommand.execute();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCStoreManager.java
private void resolveRelationships() throws Exception
{
entityBridge.resolveRelationships();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCStoreManager.java
private void startStoreManager() throws Exception
{
entityBridge.start();
// Store manager life cycle commands
startCommand = commandFactory.createStartCommand();
stopCommand = commandFactory.createStopCommand();
destroyCommand = commandFactory.createDestroyCommand();
// Entity commands
initEntityCommand = commandFactory.createInitEntityCommand();
createBeanClassInstanceCommand = commandFactory.createCreateBeanClassInstanceCommand();
findEntityCommand = commandFactory.createFindEntityCommand();
findEntitiesCommand = commandFactory.createFindEntitiesCommand();
createEntityCommand = commandFactory.createCreateEntityCommand();
postCreateEntityCommand = commandFactory.createPostCreateEntityCommand();
removeEntityCommand = commandFactory.createRemoveEntityCommand();
loadEntityCommand = commandFactory.createLoadEntityCommand();
isModifiedCommand = commandFactory.createIsModifiedCommand();
storeEntityCommand = commandFactory.createStoreEntityCommand();
activateEntityCommand = commandFactory.createActivateEntityCommand();
passivateEntityCommand = commandFactory.createPassivateEntityCommand();
// Relation commands
loadRelationCommand = commandFactory.createLoadRelationCommand();
deleteRelationsCommand = commandFactory.createDeleteRelationsCommand();
insertRelationsCommand = commandFactory.createInsertRelationsCommand();
// Create the query manager
queryManager = new JDBCQueryManager(this);
// Execute the start command, creates the tables
startCommand.execute();
// Start the query manager. At this point is creates all of the
// query commands. The must occure in the start phase, as
// queries can opperate on other entities in the application, and
// all entities are gaurenteed to be createed until the start phase.
queryManager.start();
readAheadCache.start();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCStoreManager.java
public Object createBeanClassInstance() throws Exception
{
if(createBeanClassInstanceCommand == null)
throw new IllegalStateException("createBeanClassInstanceCommand == null");
return createBeanClassInstanceCommand.execute();
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCEJBQLCompiler.java
public void compileEJBQL(String ejbql,
Class returnType,
Class[] parameterTypes,
JDBCQueryMetaData metadata) throws Exception
{
// reset all state variables
reset();
// set input arguemts
this.returnType = returnType;
this.parameterTypes = parameterTypes;
this.readAhead = metadata.getReadAhead();
this.lazyResultSetLoading = metadata.isLazyResultSetLoading();
// get the parser
EJBQLParser parser = new EJBQLParser(new StringReader(SQLUtil.EMPTY_STRING));
try
{
// parse the ejbql into an abstract sytax tree
ASTEJBQL ejbqlNode;
ejbqlNode = parser.parse(catalog, parameterTypes, ejbql);
// translate to sql
sql = ejbqlNode.jjtAccept(this, new StringBuffer()).toString();
}
catch(Exception e)
{
// if there is a problem reset the state before exiting
reset();
throw e;
}
catch(Error e)
{
// lame javacc lexer throws Errors
reset();
throw e;
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCEJBQLCompiler.java
public void compileJBossQL(String ejbql,
Class returnType,
Class[] parameterTypes,
JDBCQueryMetaData metadata)
throws Exception
{
// reset all state variables
reset();
// set input arguemts
this.returnType = returnType;
this.parameterTypes = parameterTypes;
this.readAhead = metadata.getReadAhead();
this.lazyResultSetLoading = metadata.isLazyResultSetLoading();
// get the parser
JBossQLParser parser = new JBossQLParser(new StringReader(SQLUtil.EMPTY_STRING));
try
{
// parse the ejbql into an abstract sytax tree
ASTEJBQL ejbqlNode;
ejbqlNode = parser.parse(catalog, parameterTypes, ejbql);
// translate to sql
sql = ejbqlNode.jjtAccept(this, new StringBuffer()).toString();
}
catch(Exception e)
{
// if there is a problem reset the state before exiting
reset();
throw e;
}
catch(Error e)
{
// lame javacc lexer throws Errors
reset();
throw e;
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCDeleteRelationsCommand.java
private void setParameters(PreparedStatement ps, RelationData relationData, Iterator pairs)
throws Exception
{
int index = 1;
JDBCCMPFieldBridge[] leftFields = (JDBCCMPFieldBridge[])relationData.getLeftCMRField().getTableKeyFields();
JDBCCMPFieldBridge[] rightFields = (JDBCCMPFieldBridge[])relationData.getRightCMRField().getTableKeyFields();
int keyIndex = 0;
while(pairs.hasNext())
{
RelationPair pair = (RelationPair)pairs.next();
// left keys
Object leftId = pair.getLeftId();
for(int i = 0; i < leftFields.length; ++i)
{
index = leftFields[i].setPrimaryKeyParameters(ps, index, leftId);
}
// right keys
Object rightId = pair.getRightId();
for(int i = 0; i < rightFields.length; ++i)
{
index = rightFields[i].setPrimaryKeyParameters(ps, index, rightId);
}
if(maxKeysInDelete > 0)
{
++keyIndex;
if(keyIndex == maxKeysInDelete)
{
break;
}
}
}
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCCommandFactory.java
public JDBCCreateBeanClassInstanceCommand
createCreateBeanClassInstanceCommand() throws Exception
{
return new JDBCCreateBeanClassInstanceCommand(manager);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/QueryParameter.java
public void set(Logger log, PreparedStatement ps, int index, Object[] args)
throws Exception
{
Object arg = args[argNum];
JDBCParameterSetter param;
if(field != null)
{
if(!isPrimaryKeyParameter)
{
if(arg instanceof EJBObject)
{
arg = ((EJBObject)arg).getPrimaryKey();
}
else if(arg instanceof EJBLocalObject)
{
arg = ((EJBLocalObject)arg).getPrimaryKey();
}
else
{
throw new IllegalArgumentException("Expected an instanc of " +
"EJBObject or EJBLocalObject, but got an instance of " +
arg.getClass().getName());
}
}
arg = field.getPrimaryKeyValue(arg);
// use mapper
final JDBCType jdbcType = field.getJDBCType();
arg = jdbcType.getColumnValue(0, arg);
param = jdbcType.getParameterSetter()[0];
}
else if(property != null)
{
arg = property.getColumnValue(arg);
param = property.getParameterSetter();
}
else
{
if(type != null)
{
arg = type.getColumnValue(0, arg);
param = type.getParameterSetter()[0];
}
else
{
param = JDBCUtil.getParameterSetter(jdbcType, arg == null ? null : arg.getClass());
}
}
param.set(ps, index, jdbcType, arg, log);
//JDBCUtil.setParameter(log, ps, index, jdbcType, arg);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/bridge/SecurityActions.java
public Object run() throws Exception
{
return (Subject) PolicyContext.getContext(SUBJECT_CONTEXT_KEY);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/bridge/SecurityActions.java
static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain)
throws PrivilegedActionException
{
AccessController.doPrivileged(new PrivilegedExceptionAction(){
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(p, cred, null, domain);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}});
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/bridge/SecurityActions.java
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(p, cred, null, domain);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/bridge/SecurityActions.java
static void createAndSetSecurityContext(final Principal p, final Object cred, final String domain,
final Subject subject) throws PrivilegedActionException
{
AccessController.doPrivileged(new PrivilegedExceptionAction(){
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
sc.getUtil().createSubjectInfo(p, cred, subject);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}});
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/bridge/SecurityActions.java
public Object run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(domain);
sc.getUtil().createSubjectInfo(p, cred, subject);
SecurityContextAssociation.setSecurityContext(sc);
return null;
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/bridge/JDBCSelectorBridge.java
public Object invoke(EntityEnterpriseContext ctx, Method method, Object[] args)
throws Exception
{
Transaction tx = (ctx != null ? ctx.getTransaction() : tm.getTransaction());
if(syncBeforeSelect)
{
EntityContainer.synchronizeEntitiesWithinTransaction(tx);
}
return execute(args);
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCTypeComplexProperty.java
public Object getColumnValue(Object value) throws Exception
{
Object[] noArgs = new Object[0];
for(int i = 0; i < getters.length; i++)
{
if(value == null)
{
return null;
}
value = getters[i].invoke(value, noArgs);
}
return value;
}
// in src/main/java/org/jboss/ejb/plugins/cmp/jdbc/JDBCTypeComplexProperty.java
public Object setColumnValue(
Object value,
Object columnValue) throws Exception
{
// Used for invocation of get and set
Object[] noArgs = new Object[0];
Object[] singleArg = new Object[1];
// save the first value to return
Object returnValue = value;
// get the second to last object in the chain
for(int i = 0; i < getters.length - 1; i++)
{
// get the next object in chain
Object next = getters[i].invoke(value, noArgs);
// the next object is null creat it
if(next == null)
{
// new type based on getter
next = getters[i].getReturnType().newInstance();
// and set it into the current value
singleArg[0] = next;
setters[i].invoke(value, singleArg);
}
// update value to the next in chain
value = next;
}
// value is now the object on which we need to set the column value
singleArg[0] = columnValue;
setters[setters.length - 1].invoke(value, singleArg);
// return the first object in call chain
return returnValue;
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInstancePool.java
public EnterpriseContext get()
throws Exception
{
boolean trace = log.isTraceEnabled();
if( trace )
log.trace("Get instance "+this+"#"+pool.size()+"#"+getContainer().getBeanClass());
if( strictMaxSize != null )
{
// Block until an instance is available
boolean acquired = strictMaxSize.attempt(strictTimeout);
if( trace )
log.trace("Acquired("+acquired+") strictMaxSize semaphore, remaining="+strictMaxSize.permits());
if( acquired == false )
throw new EJBException("Failed to acquire the pool semaphore, strictTimeout="+strictTimeout);
}
synchronized (pool)
{
if ( pool.isEmpty() == false )
{
return (EnterpriseContext) pool.removeFirst();
}
}
// Pool is empty, create an instance
try
{
Object instance = container.createBeanClassInstance();
return create(instance);
}
catch (Throwable e)
{
// Release the strict max size mutex if it exists
if( strictMaxSize != null )
{
strictMaxSize.release();
}
// Don't wrap CreateExceptions
if( e instanceof CreateException )
throw (CreateException) e;
// Wrap e in an Exception if needed
Exception ex = null;
if(e instanceof Exception)
{
ex = (Exception)e;
} else
{
ex = new UndeclaredThrowableException(e);
}
throw new EJBException("Could not instantiate bean", ex);
}
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInstancePool.java
protected void createService() throws Exception
{
if( this.isStrict == Boolean.TRUE )
this.strictMaxSize = new FIFOSemaphore(this.maxSize);
}
// in src/main/java/org/jboss/ejb/plugins/AbstractInstancePool.java
protected void destroyService() throws Exception
{
freeAll();
this.strictMaxSize = null;
}
// in src/main/java/org/jboss/ejb/plugins/PerTxEntityInstanceCache.java
public void create() throws Exception
{
}
// in src/main/java/org/jboss/ejb/plugins/PerTxEntityInstanceCache.java
public void start() throws Exception
{
}
// in src/main/java/org/jboss/ejb/plugins/EntityMultiInstanceInterceptor.java
public Object invokeHome(Invocation mi)
throws Exception
{
// Get context
EntityContainer ec = (EntityContainer) getContainer();
EntityEnterpriseContext ctx = (EntityEnterpriseContext) ec.getInstancePool().get();
// Pass it to the method invocation
mi.setEnterpriseContext(ctx);
// Give it the transaction
ctx.setTransaction(mi.getTransaction());
// Set the current security information
ctx.setPrincipal(mi.getPrincipal());
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_HOME);
Object result;
try
{
// Invoke through interceptors
result = getNext().invokeHome(mi);
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
// No id, means we can put the context back in the pool
if (ctx.getId() == null)
{
ctx.setTransaction(null);
ec.getInstancePool().free(ctx);
}
// We are done
return result;
}
// in src/main/java/org/jboss/ejb/plugins/EntityMultiInstanceInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
// The key
Object key = mi.getId();
EntityEnterpriseContext ctx = null;
EntityContainer ec = (EntityContainer) container;
if (mi.getTransaction() != null)
{
//ctx = ec.getTxEntityMap().getCtx(mi.getTransaction(), key);
}
if (ctx == null)
{
InstancePool pool = ec.getInstancePool();
try
{
ctx = (EntityEnterpriseContext) pool.get();
}
catch (EJBException e)
{
throw e;
}
catch (RemoteException e)
{
throw e;
}
catch (Exception e)
{
InvocationType type = mi.getType();
boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
if (isLocal)
throw new EJBException("Unable to get an instance from the pool", e);
else
throw new RemoteException("Unable to get an intance from the pool", e);
}
ctx.setCacheKey(key);
ctx.setId(key);
EntityPersistenceManager pm = ec.getPersistenceManager();
pm.activateEntity(ctx);
}
boolean trace = log.isTraceEnabled();
if( trace ) log.trace("Begin invoke, key="+key);
// Associate transaction, in the new design the lock already has the transaction from the
// previous interceptor
ctx.setTransaction(mi.getTransaction());
// Set the current security information
ctx.setPrincipal(mi.getPrincipal());
// Set the JACC EnterpriseBean PolicyContextHandler data
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx.getInstance());
// Set context on the method invocation
mi.setEnterpriseContext(ctx);
if (ejbTimeout.equals(mi.getMethod()))
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_TIMEOUT);
else
AllowedOperationsAssociation.pushInMethodFlag(IN_BUSINESS_METHOD);
try
{
Object ret = getNext().invoke(mi);
return ret;
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
}
}
// in src/main/java/org/jboss/ejb/plugins/LogInterceptor.java
public void create()
throws Exception
{
super.start();
BeanMetaData md = getContainer().getBeanMetaData();
ejbName = md.getEjbName();
// Should we log call details
callLogging = md.getContainerConfiguration().getCallLogging();
}
// in src/main/java/org/jboss/ejb/plugins/LogInterceptor.java
public Object invokeHome(Invocation invocation)
throws Exception
{
String methodName;
if (invocation.getMethod() != null)
{
methodName = invocation.getMethod().getName();
}
else
{
methodName = "<no method>";
}
boolean trace = log.isTraceEnabled();
if (trace)
{
log.trace("Start method=" + methodName);
}
// Log call details
if (callLogging)
{
StringBuffer str = new StringBuffer("InvokeHome: ");
str.append(methodName);
str.append("(");
Object[] args = invocation.getArguments();
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
if (i > 0)
{
str.append(",");
}
str.append(args[i]);
}
}
str.append(")");
log.debug(str.toString());
}
try
{
return getNext().invokeHome(invocation);
}
catch(Throwable e)
{
throw handleException(e, invocation);
}
finally
{
if (trace)
{
log.trace("End method=" + methodName);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/LogInterceptor.java
public Object invoke(Invocation invocation)
throws Exception
{
String methodName;
if (invocation.getMethod() != null)
{
methodName = invocation.getMethod().getName();
}
else
{
methodName = "<no method>";
}
boolean trace = log.isTraceEnabled();
if (trace)
{
log.trace("Start method=" + methodName);
}
// Log call details
if (callLogging)
{
StringBuffer str = new StringBuffer("Invoke: ");
if (invocation.getId() != null)
{
str.append("[");
str.append(invocation.getId().toString());
str.append("] ");
}
str.append(methodName);
str.append("(");
Object[] args = invocation.getArguments();
if (args != null)
{
for (int i = 0; i < args.length; i++)
{
if (i > 0)
{
str.append(",");
}
str.append(args[i]);
}
}
str.append(")");
log.debug(str.toString());
}
try
{
return getNext().invoke(invocation);
}
catch(Throwable e)
{
throw handleException(e, invocation);
}
finally
{
if (trace)
{
log.trace("End method=" + methodName);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/AbstractTxInterceptorBMT.java
public void create() throws Exception
{
// Do initialization in superclass.
super.create();
// bind java:comp/UserTransaction
RefAddr refAddr = new RefAddr("userTransaction")
{
/** This is never really serialized */
private static final long serialVersionUID = -8228448967597474960L;
public Object getContent()
{
return userTransaction;
}
};
Reference ref = new Reference("javax.transaction.UserTransaction", refAddr, new UserTxFactory().getClass()
.getName(), null);
((Context) new InitialContext().lookup("java:comp/")).bind("UserTransaction", ref);
}
// in src/main/java/org/jboss/ejb/plugins/AbstractTxInterceptorBMT.java
protected Object invokeNext(Invocation mi) throws Exception
{
// Save the transaction that comes with the MI
Transaction oldTransaction = mi.getTransaction();
// Get old threadlocal: It may be non-null if one BMT bean does a local
// call to another.
Object oldUserTx = userTransaction.get();
// Suspend any transaction associated with the thread: It may be
// non-null on optimized local calls.
Transaction threadTx = tm.suspend();
try
{
EnterpriseContext ctx = ((EnterpriseContext) mi.getEnterpriseContext());
// Set the threadlocal to the userTransaction of the instance
try
{
AllowedOperationsAssociation.pushInMethodFlag(IN_INTERCEPTOR_METHOD);
userTransaction.set(ctx.getEJBContext().getUserTransaction());
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
}
// Get the bean instance transaction
Transaction beanTx = ctx.getTransaction();
// Resume the bean instance transaction
// only if it not null, some TMs can't resume(null), e.g. Tyrex
if (beanTx != null)
tm.resume(beanTx);
// Let the MI know about our new transaction
mi.setTransaction(beanTx);
try
{
// Let the superclass call next interceptor and do the exception
// handling
return super.invokeNext(mi, false);
}
finally
{
try
{
if (stateless)
checkStatelessDone();
else
checkBadStateful();
}
finally
{
tm.suspend();
}
}
}
finally
{
// Reset threadlocal to its old value
userTransaction.set(oldUserTx);
// Restore old MI transaction
// OSH: Why ???
mi.setTransaction(oldTransaction);
// If we had a Tx associated with the thread reassociate
if (threadTx != null)
tm.resume(threadTx);
}
}
// in src/main/java/org/jboss/ejb/plugins/AbstractTxInterceptorBMT.java
public Object getObjectInstance(Object ref, Name name, Context nameCtx, Hashtable environment) throws Exception
{
// The ref is a list with only one RefAddr ...
RefAddr refAddr = ((Reference) ref).get(0);
// ... whose content is the threadlocal
ThreadLocal threadLocal = (ThreadLocal) refAddr.getContent();
// The threadlocal holds the right UserTransaction
return threadLocal.get();
}
// in src/main/java/org/jboss/ejb/plugins/SSLSessionInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
extractSessionPrincipal(mi);
Object returnValue = getNext().invokeHome(mi);
return returnValue;
}
// in src/main/java/org/jboss/ejb/plugins/SSLSessionInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
extractSessionPrincipal(mi);
Object returnValue = getNext().invoke(mi);
return returnValue;
}
// in src/main/java/org/jboss/ejb/plugins/MessageDrivenInstancePool.java
protected void createService() throws Exception
{
super.createService();
// for MDB, we *do* pool
this.reclaim = true;
}
// in src/main/java/org/jboss/ejb/plugins/MessageDrivenInstancePool.java
protected EnterpriseContext create(Object instance)
throws Exception
{
return new MessageDrivenEnterpriseContext(instance, getContainer());
}
// in src/main/java/org/jboss/ejb/plugins/MessageDrivenTxInterceptorBMT.java
public Object invoke(Invocation mi)
throws Exception
{
return invokeNext(mi);
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java
public Object invokeHome(Invocation mi)
throws Exception
{
// Invocation on the handle, we don't need a bean instance
if (getEJBObject.equals(mi.getMethod()))
return getNext().invokeHome(mi);
// get a new context from the pool (this is a home method call)
InstancePool pool = container.getInstancePool();
EnterpriseContext ctx = pool.get();
// set the context on the Invocation
mi.setEnterpriseContext(ctx);
// It is a new context for sure so we can lock it
ctx.lock();
// Set the current security information
/**
* JBAS-3976: Setting principal on the context has been moved to a separate interceptor
*/
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_HOME);
try
{
// Invoke through interceptors
return getNext().invokeHome(mi);
}
finally
{
synchronized (ctx)
{
AllowedOperationsAssociation.popInMethodFlag();
// Release the lock
ctx.unlock();
// Still free? Not free if create() was called successfully
if (ctx.getId() == null)
{
pool.free(ctx);
}
}
}
}
// in src/main/java/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
InstanceCache cache = container.getInstanceCache();
InstancePool pool = container.getInstancePool();
Object methodID = mi.getId();
EnterpriseContext ctx = null;
BeanLock lock = container.getLockManager().getLock(methodID);
boolean callerRunAsIdentityPresent = SecurityActions.peekRunAsIdentity() != null;
boolean pushSecurityContext = SecurityActions.getSecurityContext() == null;
try
{
/* The security context must be established before the cache
lookup because the activation of a session should have the caller's
security context as ejbActivate is allowed to call other secured
resources. Since the pm makes the ejbActivate call, we need to
set the caller's security context. The only reason this shows up for
stateful session is that we moved the SecurityInterceptor to after
the instance interceptor to allow security exceptions to result in
invalidation of the session. This may be too literal an interpretation
of the ejb spec requirement that runtime exceptions should invalidate
the session.
*/
if(!callerRunAsIdentityPresent && pushSecurityContext)
{
AuthenticationManager am = container.getSecurityManager();
String securityDomain = SecurityConstants.DEFAULT_APPLICATION_POLICY;
if(am != null)
securityDomain = am.getSecurityDomain();
SecurityActions.createAndSetSecurityContext(mi.getPrincipal(), mi.getCredential(),
securityDomain , null);
//SecurityActions.pushSubjectContext(mi.getPrincipal(), mi.getCredential(), null);
}
lock.sync();
try
{
// Get context
try
{
ctx = cache.get(methodID);
}
catch (NoSuchObjectException e)
{
if (mi.isLocal())
throw new NoSuchObjectLocalException(e.getMessage());
else
throw e;
}
catch (EJBException e)
{
throw e;
}
catch (RemoteException e)
{
throw e;
}
catch (Exception e)
{
InvocationType type = mi.getType();
boolean isLocal = (type == InvocationType.LOCAL || type == InvocationType.LOCALHOME);
if (isLocal)
throw new EJBException("Unable to get an instance from the pool/cache", e);
else
throw new RemoteException("Unable to get an intance from the pool/cache", e);
}
// Associate it with the method invocation
mi.setEnterpriseContext(ctx);
// Set the JACC EnterpriseBean PolicyContextHandler data
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(ctx.getInstance());
// BMT beans will lock and replace tx no matter what, CMT do work on transaction
boolean isBMT = ((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx();
if (isBMT == false)
{
// Do we have a running transaction with the context
if (ctx.getTransaction() != null &&
// And are we trying to enter with another transaction
!ctx.getTransaction().equals(mi.getTransaction()))
{
// Calls must be in the same transaction
StringBuffer msg = new StringBuffer("Application Error: " +
"tried to enter Stateful bean with different tx context");
msg.append(", contextTx: " + ctx.getTransaction());
msg.append(", methodTx: " + mi.getTransaction());
throw new EJBException(msg.toString());
}
//If the instance will participate in a new transaction we register a sync for it
if (ctx.getTransaction() == null && mi.getTransaction() != null)
{
register(ctx, mi.getTransaction(), lock);
}
}
if (!ctx.isLocked())
{
//take it!
ctx.lock();
}
else
{
if (!isCallAllowed(mi))
{
// Concurent calls are not allowed
throw new EJBException("Application Error: no concurrent " +
"calls on stateful beans");
}
else
{
ctx.lock();
}
}
}
finally
{
lock.releaseSync();
}
// Set the current security information
/**
* JBAS-3976: Setting principal on the context has been moved to a separate interceptor
*/
if (ejbTimeout.equals(mi.getMethod()))
AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_TIMEOUT);
else
AllowedOperationsAssociation.pushInMethodFlag(IN_BUSINESS_METHOD);
boolean validContext = true;
try
{
// Invoke through interceptors
Object ret = getNext().invoke(mi);
return ret;
}
catch (RemoteException e)
{
// Discard instance
cache.remove(methodID);
pool.discard(ctx);
validContext = false;
throw e;
}
catch (RuntimeException e)
{
// Discard instance
cache.remove(methodID);
pool.discard(ctx);
validContext = false;
throw e;
}
catch (Error e)
{
// Discard instance
cache.remove(methodID);
pool.discard(ctx);
validContext = false;
throw e;
}
finally
{
AllowedOperationsAssociation.popInMethodFlag();
if (validContext)
{
// Still a valid instance
lock.sync();
try
{
// release it
ctx.unlock();
// if removed, remove from cache
if (ctx.getId() == null)
{
// Remove from cache
cache.remove(methodID);
pool.free(ctx);
}
}
finally
{
lock.releaseSync();
}
}
}
}
finally
{
container.getLockManager().removeLockRef(lock.getId());
if(!callerRunAsIdentityPresent && pushSecurityContext)
SecurityActions.clearSecurityContext();
EnterpriseBeanPolicyContextHandler.setEnterpriseBean(null);
}
}
// in src/main/java/org/jboss/ejb/plugins/SecurityInterceptor.java
public void start() throws Exception
{
super.start();
authenticationObserver = (AuthenticationObserver) Registry.lookup(AuthenticationObserver.KEY);
//Take care of hot deployed security domains
if (container != null)
{
securityManager = container.getSecurityManager();
if (securityManager != null)
{
appSecurityDomain = securityManager.getSecurityDomain();
appSecurityDomain = SecurityUtil.unprefixSecurityDomain(appSecurityDomain);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/SecurityInterceptor.java
public Object invokeHome(Invocation mi) throws Exception
{
boolean isInvoke = false;
return process(mi, isInvoke);
}
// in src/main/java/org/jboss/ejb/plugins/SecurityInterceptor.java
public Object invoke(Invocation mi) throws Exception
{
boolean isInvoke = true;
return process(mi, isInvoke);
}
// in src/main/java/org/jboss/ejb/plugins/SecurityInterceptor.java
private Object process(Invocation mi, boolean isInvoke) throws Exception
{
if (this.shouldBypassSecurity(mi))
{
if (log.isTraceEnabled())
log.trace("Bypass security for invoke or invokeHome");
if (isInvoke)
return getNext().invoke(mi);
else
return getNext().invokeHome(mi);
}
SecurityContext sc = SecurityActions.getSecurityContext();
if (sc == null)
throw new IllegalStateException("Security Context is null");
RunAs callerRunAsIdentity = sc.getIncomingRunAs();
if (log.isTraceEnabled())
log.trace("Caller RunAs=" + callerRunAsIdentity + ": useCallerIdentity=" + this.isUseCallerIdentity);
// Authenticate the subject and apply any declarative security checks
try
{
checkSecurityContext(mi, callerRunAsIdentity);
}
catch (Exception e)
{
log.error("Error in Security Interceptor", e);
throw e;
}
RunAs runAsIdentityToPush = runAsIdentity;
/**
* Special case: if <use-caller-identity> configured and
* the caller is arriving with a run-as, we need to push that run-as
*/
if (callerRunAsIdentity != null && this.isUseCallerIdentity)
runAsIdentityToPush = callerRunAsIdentity;
/* If a run-as role was specified, push it so that any calls made
by this bean will have the runAsRole available for declarative
security checks.
*/
SecurityActions.pushRunAsIdentity(runAsIdentityToPush);
try
{
if (isInvoke)
return getNext().invoke(mi);
else
return getNext().invokeHome(mi);
}
finally
{
SecurityActions.popRunAsIdentity();
SecurityActions.popSubjectContext();
}
}
// in src/main/java/org/jboss/ejb/plugins/SecurityInterceptor.java
private void checkSecurityContext(Invocation mi, RunAs callerRunAsIdentity) throws Exception
{
Principal principal = mi.getPrincipal();
Object credential = mi.getCredential();
boolean trace = log.isTraceEnabled();
// If there is not a security manager then there is no authentication required
Method m = mi.getMethod();
boolean containerMethod = m == null || m.equals(ejbTimeout);
if (containerMethod == true || securityManager == null || container == null)
{
// Allow for the propagation of caller info to other beans
SecurityActions.pushSubjectContext(principal, credential, null);
return;
}
if (realmMapping == null)
{
throw new SecurityException("Role mapping manager has not been set");
}
SecurityContext sc = SecurityActions.getSecurityContext();
EJBAuthenticationHelper helper = SecurityHelperFactory.getEJBAuthenticationHelper(sc);
boolean isTrusted = containsTrustableRunAs(sc) || helper.isTrusted();
if (!isTrusted)
{
// Check the security info from the method invocation
Subject subject = new Subject();
if (SecurityActions.isValid(helper, subject, m.getName()) == false)
{
// Notify authentication observer
if (authenticationObserver != null)
authenticationObserver.authenticationFailed();
// Else throw a generic SecurityException
String msg = "Authentication exception, principal=" + principal;
throw new SecurityException(msg);
}
else
{
SecurityActions.pushSubjectContext(principal, credential, subject);
if (trace)
{
log.trace("Authenticated principal=" + principal + " in security domain=" + sc.getSecurityDomain());
}
}
}
else
{
// Duplicate the current subject context on the stack since
//SecurityActions.dupSubjectContext();
SecurityActions.pushRunAsIdentity(callerRunAsIdentity);
}
Method ejbMethod = mi.getMethod();
// Ignore internal container calls
if (ejbMethod == null)
return;
// Get the caller
Subject caller = SecurityActions.getContextSubject();
if (caller == null)
throw new IllegalStateException("Authenticated User. But caller subject is null");
//Establish the deployment rolename-principalset custom mapping(if available)
SecurityRolesAssociation.setSecurityRoles(this.deploymentRoles);
boolean isAuthorized = false;
Set<Principal> methodRoles = container.getMethodPermissions(ejbMethod, mi.getType());
SecurityContext currentSC = SecurityActions.getSecurityContext();
if (SecurityActions.getSecurityManagement(currentSC) == null)
SecurityActions.setSecurityManagement(currentSC, securityManagement);
AbstractEJBAuthorizationHelper authorizationHelper = SecurityHelperFactory.getEJBAuthorizationHelper(sc);
authorizationHelper.setPolicyRegistration(container.getPolicyRegistration());
isAuthorized = SecurityActions.authorize(authorizationHelper, ejbName, ejbMethod, mi.getPrincipal(),
mi.getType().toInterfaceString(), ejbCS, caller, callerRunAsIdentity, container.getJaccContextID(),
new SimpleRoleGroup(methodRoles));
if (!isAuthorized)
{
String msg = "Denied: caller with subject=" + caller + " and security context post-mapping roles="
+ SecurityActions.getRolesFromSecurityContext(currentSC) + ": ejbMethod=" + ejbMethod;
throw new SecurityException(msg);
}
}
// in src/main/java/org/jboss/ejb/plugins/SecurityInterceptor.java
private boolean shouldBypassSecurity(Invocation mi) throws Exception
{
// If there is not a security manager then there is no authentication required
Method m = mi.getMethod();
boolean containerMethod = m == null || m.equals(ejbTimeout);
if (containerMethod == true || securityManager == null || container == null)
{
// Allow for the propagation of caller info to other beans
SecurityActions.createAndSetSecurityContext(mi.getPrincipal(), mi.getCredential(), "BYPASSED-SECURITY");
if (this.runAsIdentity != null)
SecurityActions.pushRunAsIdentity(runAsIdentity);
return true;
}
return false;
}
// in src/main/java/org/jboss/ejb/plugins/ProxyFactoryFinderInterceptor.java
public void create() throws Exception
{
}
// in src/main/java/org/jboss/ejb/plugins/ProxyFactoryFinderInterceptor.java
protected void setProxyFactory(String invokerBinding, Invocation mi) throws Exception
{
// if (BeanMetaData.LOCAL_INVOKER_PROXY_BINDING.equals(invokerBinding)) return;
if (invokerBinding == null)
{
log.trace("invokerBInding is null in ProxyFactoryFinder");
return;
}
/*
if (invokerBinding == null)
{
log.error("***************** invokerBinding is null ********");
log.error("Method name: " + mi.getMethod().getName());
log.error("jmx name: " + container.getJmxName().toString());
new Throwable().printStackTrace();
log.error("*************************");
throw new EJBException("Couldn't insert proxy factory, " +
"invokerBinding was null");
}
*/
Object proxyFactory = container.lookupProxyFactory(invokerBinding);
if (proxyFactory == null)
{
String methodName;
if(mi.getMethod() != null) {
methodName = mi.getMethod().getName();
} else
{
methodName ="<no method>";
}
log.error("***************** proxyFactory is null ********");
log.error("Method name: " + methodName);
log.error("jmx name: " + container.getJmxName().toString());
log.error("invokerBinding: " + invokerBinding);
log.error("Stack trace", new Throwable());
log.error("*************************");
throw new EJBException("Couldn't find proxy factory");
}
container.setProxyFactory(proxyFactory);
}
// in src/main/java/org/jboss/ejb/plugins/ProxyFactoryFinderInterceptor.java
public Object invokeHome(Invocation mi)
throws Exception
{
String invokerBinding =
(String)mi.getAsIsValue(InvocationKey.INVOKER_PROXY_BINDING);
setProxyFactory(invokerBinding, mi);
String oldInvokerBinding = ENCThreadLocalKey.getKey();
// Only override current ENC binding if we're not local
// if ((!BeanMetaData.LOCAL_INVOKER_PROXY_BINDING.equals(invokerBinding)) || oldInvokerBinding == null)
if (invokerBinding != null || oldInvokerBinding == null)
{
ENCThreadLocalKey.setKey(invokerBinding);
}
Interceptor next = getNext();
Object value = null;
try
{
value = next.invokeHome(mi);
}
finally
{
ENCThreadLocalKey.setKey(oldInvokerBinding);
// JBAS-4192 clear the container's thread local
container.setProxyFactory(null);
}
return value;
}
// in src/main/java/org/jboss/ejb/plugins/ProxyFactoryFinderInterceptor.java
public Object invoke(Invocation mi)
throws Exception
{
String invokerBinding =
(String)mi.getAsIsValue(InvocationKey.INVOKER_PROXY_BINDING);
setProxyFactory(invokerBinding, mi);
String oldInvokerBinding = ENCThreadLocalKey.getKey();
// Only override current ENC binding if we're not local or there has not been a previous call
// if ((!BeanMetaData.LOCAL_INVOKER_PROXY_BINDING.equals(invokerBinding)) || oldInvokerBinding == null)
if (invokerBinding != null || oldInvokerBinding == null)
{
ENCThreadLocalKey.setKey(invokerBinding);
}
Interceptor next = getNext();
Object value = null;
try
{
value = next.invoke(mi);
}
finally
{
ENCThreadLocalKey.setKey(oldInvokerBinding);
// JBAS-4192 clear the container's thread local
container.setProxyFactory(null);
}
return value;
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorBMT.java
public void create()
throws Exception
{
// Do initialization in superclass.
super.create();
// Set the atateless attribute
stateless = ((SessionMetaData)container.getBeanMetaData()).isStateless();
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorBMT.java
public Object invokeHome(Invocation mi)
throws Exception
{
// stateless: no context, no transaction, no call to the instance
if (stateless || mi.getEnterpriseContext() == null)
return getNext().invokeHome(mi);
else
return invokeNext(mi);
}
// in src/main/java/org/jboss/ejb/plugins/TxInterceptorBMT.java
public Object invoke(Invocation mi)
throws Exception
{
return invokeNext(mi);
}
// in src/main/java/org/jboss/ejb/plugins/security/SecurityActions.java
static SecurityContext createAndSetSecurityContext(final String domain,
final String fqnClassName) throws PrivilegedActionException
{
return AccessController.doPrivileged(new PrivilegedExceptionAction<SecurityContext>()
{
public SecurityContext run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(domain, fqnClassName);
setSecurityContext(sc);
return sc;
}}
);
}
// in src/main/java/org/jboss/ejb/plugins/security/SecurityActions.java
public SecurityContext run() throws Exception
{
SecurityContext sc = SecurityContextFactory.createSecurityContext(domain, fqnClassName);
setSecurityContext(sc);
return sc;
}
// in src/main/java/org/jboss/ejb/plugins/security/PreSecurityInterceptor.java
Override
public Object invoke(Invocation mi) throws Exception
{
boolean isInvoke = true;
return this.process(mi, isInvoke);
}
// in src/main/java/org/jboss/ejb/plugins/security/PreSecurityInterceptor.java
Override
public Object invokeHome(Invocation mi) throws Exception
{
boolean isInvoke = false;
return this.process(mi, isInvoke);
}
// in src/main/java/org/jboss/ejb/plugins/security/PreSecurityInterceptor.java
private Object process(Invocation mi, boolean isInvoke) throws Exception
{
//No Security in the absence of SecurityDomain
if(securityDomain == null)
{
if(isInvoke)
return getNext().invoke(mi);
else
return getNext().invokeHome(mi);
}
if (log.isTraceEnabled())
{
log.trace("process:isInvoke="+isInvoke + " bean="+ container.getServiceName());
}
SecurityIdentity si = null;
String incomingDomain = null;
Method m = mi.getMethod();
boolean isEjbTimeOutMethod = m!= null && m.getName().equals(timedObjectMethod);
//For local ejb invocations
if(mi.isLocal() && !isEjbTimeOutMethod)
{
if (log.isTraceEnabled())
{
log.trace("True mi.isLocal() && !isEjbTimeOutMethod");
}
//Cache the security context
SecurityContext sc = SecurityActions.getSecurityContext();
if(sc != null)
{
si = SecurityActions.getSecurityIdentity(sc);
incomingDomain = sc.getSecurityDomain();
}
SecurityActions.setSecurityManagement(sc, container.getSecurityManagement());
// set the container's security domain in the security context
SecurityActions.setSecurityDomain(sc, this.securityDomain);
if (log.isTraceEnabled())
{
log.trace("SecurityIdentity="+SecurityActions.trace(si));
}
//Set the security context on the invocation
mi.setSecurityContext(sc);
}
else
{
if (log.isTraceEnabled())
{
log.trace("False mi.isLocal() && !isEjbTimeOutMethod");
}
establishSecurityContext(mi);
}
try
{
//Establish the run-as on the SC as the caller SC
SecurityContext currentSC = SecurityActions.getSecurityContext();
SecurityActions.pushCallerRunAsIdentity(currentSC.getOutgoingRunAs());
if (log.isTraceEnabled())
{
log.trace("Going to the SecurityInterceptor with SC="+SecurityActions.trace(currentSC));
}
if(isInvoke)
return getNext().invoke(mi);
else
return getNext().invokeHome(mi);
}
finally
{
SecurityActions.popCallerRunAsIdentity();
if(mi.isLocal() && si != null)
SecurityActions.setSecurityIdentity(SecurityActions.getSecurityContext(), si);
if(mi.isLocal() && incomingDomain != null)
SecurityActions.setSecurityDomain(SecurityActions.getSecurityContext(), incomingDomain);
if (log.isTraceEnabled())
{
log.trace("Exit process():isInvoke="+isInvoke);
}
}
}
// in src/main/java/org/jboss/ejb/plugins/security/PreSecurityInterceptor.java
private void establishSecurityContext(Invocation mi) throws Exception
{
//For Local EJB invocations, the security context needs
//to be obtained from the thread local. For remote ejb
//invocations, the SC is obtained in the invocation
SecurityContext sc = mi.getSecurityContext();
SecurityContext newSC = SecurityActions.createAndSetSecurityContext(securityDomain,
container.getSecurityContextClassName());
if(sc != null)
{
//Get the run-as, principal, cred etc from the invocation and set it on the context
SecurityActions.setSecurityIdentity(newSC, SecurityActions.getSecurityIdentity(sc));
}
else
{
//Local EJB Invocation or some one created the Invocation object on the server side
mi.setSecurityContext(newSC);
}
//Set the SecurityManagement on the context
SecurityActions.setSecurityManagement(newSC, container.getSecurityManagement());
if (log.isTraceEnabled())
{
log.trace("establishSecurityIdentity:SecCtx="+SecurityActions.trace(newSC));
}
}
// in src/main/java/org/jboss/ejb/plugins/EntityMultiInstanceSynchronizationInterceptor.java
public void create()
throws Exception
{
super.create();
}
// in src/main/java/org/jboss/ejb/GlobalTxEntityMap.java
public void invokeEjbStore(Thread thread, EntityEnterpriseContext instance) throws Exception
{
if(instance.getId() != null)
{
EntityContainer container = (EntityContainer) instance.getContainer();
// set the context class loader before calling the store method
SecurityActions.setContextClassLoader(thread, container.getClassLoader());
container.pushENC();
try
{
// store it
container.invokeEjbStore(instance);
}
finally
{
container.popENC();
}
}
}
// in src/main/java/org/jboss/ejb/GlobalTxEntityMap.java
public void synchronize(Thread thread, Transaction tx, EntityEnterpriseContext instance)
throws Exception
{
// only synchronize if the id is not null. A null id means
// that the entity has been removed.
if(instance.getId() != null)
{
EntityContainer container = (EntityContainer) instance.getContainer();
// set the context class loader before calling the store method
SecurityActions.setContextClassLoader(thread, container.getClassLoader());
container.pushENC();
try
{
// store it
container.storeEntity(instance);
instance.setTxAssociation(SYNCHRONIZED);
}
finally
{
container.popENC();
}
}
}
// in src/main/java/org/jboss/ejb/GlobalTxEntityMap.java
public void synchronize(Thread thread, Transaction tx, EntityEnterpriseContext instance) throws Exception
{
EntityContainer container = (EntityContainer)instance.getContainer();
if(container.getPersistenceManager().isStoreRequired(instance))
{
throw new EJBException("The instance of " +
container.getBeanMetaData().getEjbName() +
" with pk=" +
instance.getId() +
" was not stored to prevent potential inconsistency of data in the database:" +
" the instance was evicted from the cache during the transaction" +
" and the database was possibly updated by another process.");
}
}
// in src/main/java/org/jboss/ejb/GlobalTxEntityMap.java
public void invokeEjbStore(Thread thread, EntityEnterpriseContext instance) throws Exception
{
GlobalTxEntityMap.SYNC_SCHEDULED.invokeEjbStore(thread, instance);
}
// in src/main/java/org/jboss/ejb/GlobalTxEntityMap.java
public void synchronize(Thread thread, Transaction tx, EntityEnterpriseContext instance) throws Exception
{
}
// in src/main/java/org/jboss/ejb/GlobalTxEntityMap.java
public void invokeEjbStore(Thread thread, EntityEnterpriseContext instance) throws Exception
{
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object createBeanClassInstance() throws Exception {
return persistenceManager.createBeanClassInstance();
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void createService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Acquire classes from CL
if (metaData.getHome() != null)
homeInterface = classLoader.loadClass(metaData.getHome());
if (metaData.getRemote() != null)
remoteInterface = classLoader.loadClass(metaData.getRemote());
// Call default init
super.createService();
// Make some additional validity checks with regards to the container configuration
checkCoherency ();
// Map the bean methods
setupBeanMapping();
// Map the home methods
setupHomeMapping();
// Map the interfaces to Long
setupMarshalledInvocationMapping();
// Try to register the instance pool as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "pool");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instancePool, poolName);
}
catch(Throwable t)
{
log.debug("Failed to register cache as mbean", t);
}
// Initialize pool
instancePool.setContainer(this);
instancePool.create();
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.create();
}
// Try to register the instance cache as an MBean
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "cache");
ObjectName cacheName = new ObjectName(containerName.getDomain(), props);
server.registerMBean(instanceCache, cacheName);
}
catch(Throwable t)
{
log.debug("Failed to register cache as mbean", t);
}
// Init instance cache
instanceCache.setContainer(this);
instanceCache.create();
// Init persistence
persistenceManager.setContainer(this);
persistenceManager.create();
// Initialize the interceptor by calling the chain
Interceptor in = interceptor;
while (in != null)
{
in.setContainer(this);
in.create();
in = in.getNext();
}
readOnly = ((EntityMetaData)metaData).isReadOnly();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void startService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Call default start
super.startService();
// Start container invokers
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.start();
}
// Start instance cache
instanceCache.start();
// Start the instance pool
instancePool.start();
Interceptor i = interceptor;
while(i != null)
{
i.start();
i = i.getNext();
}
// Restore persisted ejb timers
restoreTimers();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void stopService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
//Stop items in reverse order from start
//This assures that CachedConnectionInterceptor will get removed
//from in between this and the pm before the pm is stopped.
// Stop all interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.stop();
in = in.getNext();
}
// Stop the instance pool
instancePool.stop();
// Stop persistence
persistenceManager.stop();
// Stop instance cache
instanceCache.stop();
// Stop container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.stop();
}
// Call default stop
super.stopService();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void destroyService() throws Exception
{
// Associate thread with classloader
ClassLoader oldCl = SecurityActions.getContextClassLoader();
SecurityActions.setContextClassLoader(getClassLoader());
pushENC();
try
{
// Destroy container invoker
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
ci.destroy();
}
// Destroy instance cache
instanceCache.destroy();
instanceCache.setContainer(null);
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "cache");
ObjectName cacheName = new ObjectName(containerName.getDomain(), props);
server.unregisterMBean(cacheName);
}
catch(Throwable ignore)
{
}
// Destroy persistence
persistenceManager.destroy();
persistenceManager.setContainer(null);
// Destroy the pool
instancePool.destroy();
instancePool.setContainer(null);
try
{
ObjectName containerName = super.getJmxName();
Hashtable props = containerName.getKeyPropertyList();
props.put("plugin", "pool");
ObjectName poolName = new ObjectName(containerName.getDomain(), props);
server.unregisterMBean(poolName);
}
catch(Throwable ignore)
{
}
// Destroy all the interceptors in the chain
Interceptor in = interceptor;
while (in != null)
{
in.destroy();
in.setContainer(null);
in = in.getNext();
}
MarshalledInvocation.removeHashes(homeInterface);
MarshalledInvocation.removeHashes(remoteInterface);
// Call default destroy
super.destroyService();
}
finally
{
popENC();
// Reset classloader
SecurityActions.setContextClassLoader(oldCl);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object internalInvokeHome(Invocation mi) throws Exception
{
Method method = mi.getMethod();
if (method != null && method.getName().equals("remove"))
{
// Map to EJBHome.remove(Object) to EJBObject.remove()
InvocationType type = mi.getType();
if (type == InvocationType.HOME)
mi.setType(InvocationType.REMOTE);
else if (type == InvocationType.LOCALHOME)
mi.setType(InvocationType.LOCAL);
mi.setMethod(EJBOBJECT_REMOVE);
// Handle or primary key?
Object arg = mi.getArguments()[0];
if (arg instanceof Handle)
{
if (arg == null)
throw new RemoteException("Null handle");
Handle handle = (Handle) arg;
EJBObject ejbObject = handle.getEJBObject();
mi.setId(ejbObject.getPrimaryKey());
}
else
mi.setId(arg);
mi.setArguments(new Object[0]);
return getInterceptor().invoke(mi);
}
// Invoke through interceptors
return getInterceptor().invokeHome(mi);
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object internalInvoke(Invocation mi) throws Exception
{
// Invoke through interceptors
return getInterceptor().invoke(mi);
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public EJBLocalObject createLocalHome(Invocation mi)
throws Exception
{
// The persistence manager takes care of the wiring and creating the EJBLocalObject
final EntityEnterpriseContext ctx = (EntityEnterpriseContext)mi.getEnterpriseContext();
getPersistenceManager().createEntity(mi.getMethod(), mi.getArguments(), ctx);
// The context implicitely carries the EJBObject
createCount++;
return localProxyFactory.getEntityEJBLocalObject(ctx.getId(), true);
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public void postCreateLocalHome(Invocation mi) throws Exception
{
// The persistence manager takes care of the post create step
getPersistenceManager().postCreateEntity(mi.getMethod(),mi.getArguments(),
(EntityEnterpriseContext) mi.getEnterpriseContext());
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object findLocal(Invocation mi)
throws Exception
{
Method method = mi.getMethod();
Object[] args = mi.getArguments();
EntityEnterpriseContext instance = (EntityEnterpriseContext)mi.getEnterpriseContext();
boolean syncOnCommitOnly = metaData.getContainerConfiguration().getSyncOnCommitOnly();
Transaction tx = mi.getTransaction();
Class returnType = method.getReturnType();
if (Collection.class.isAssignableFrom(returnType) || returnType == Enumeration.class)
{
// as per the spec 9.6.4, entities must be synchronized with the datastore when an ejbFind<METHOD> is called.
if (!syncOnCommitOnly)
{
synchronizeEntitiesWithinTransaction(tx);
}
// Iterator finder
Collection c = getPersistenceManager().findEntities(method, args, instance, localProxyFactory);
// BMP entity finder methods are allowed to return java.util.Enumeration.
if (returnType == Enumeration.class)
{
return java.util.Collections.enumeration(c);
}
else
{
return c;
}
}
else
{
return findSingleObject(tx, method, args, instance, localProxyFactory);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object find(Invocation mi) throws Exception
{
EJBProxyFactory ci = getProxyFactory();
if (ci == null)
{
String msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor";
throw new IllegalStateException(msg);
}
Method method = mi.getMethod();
Object[] args = mi.getArguments();
EntityEnterpriseContext instance = (EntityEnterpriseContext)mi.getEnterpriseContext();
boolean syncOnCommitOnly = metaData.getContainerConfiguration().getSyncOnCommitOnly();
Transaction tx = mi.getTransaction();
Class returnType = method.getReturnType();
if (Collection.class.isAssignableFrom(returnType) || returnType == Enumeration.class)
{
// as per the spec 9.6.4, entities must be synchronized with the datastore when an ejbFind<METHOD> is called.
if (!syncOnCommitOnly)
{
synchronizeEntitiesWithinTransaction(tx);
}
// Iterator finder
Collection c = getPersistenceManager().findEntities(method, args, instance, ci);
// BMP entity finder methods are allowed to return java.util.Enumeration.
// We need a serializable Enumeration, so we can't use Collections.enumeration()
if (returnType == Enumeration.class)
{
return new SerializableEnumeration(c);
}
else
{
return c;
}
}
else
{
return findSingleObject(tx, method, args, instance, ci);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public void invokeEjbStore(EntityEnterpriseContext ctx) throws Exception
{
if (ctx.getId() != null)
{
final EntityPersistenceManager pm = getPersistenceManager();
pm.invokeEjbStore(ctx);
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public void storeEntity(EntityEnterpriseContext ctx) throws Exception
{
if (ctx.getId() != null)
{
final EntityPersistenceManager pm = getPersistenceManager();
if(pm.isStoreRequired(ctx))
{
pm.storeEntity(ctx);
}
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public void postCreateHome(Invocation mi) throws Exception
{
// The persistence manager takes care of the post create step
getPersistenceManager().postCreateEntity(mi.getMethod(),mi.getArguments(),
(EntityEnterpriseContext) mi.getEnterpriseContext());
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public EJBObject createHome(Invocation mi)
throws Exception
{
// The persistence manager takes care of the wiring and creating the EJBObject
getPersistenceManager().createEntity(mi.getMethod(),mi.getArguments(),
(EntityEnterpriseContext) mi.getEnterpriseContext());
// The context implicitely carries the EJBObject
createCount++;
return ((EntityEnterpriseContext)mi.getEnterpriseContext()).getEJBObject();
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
private void setupHomeMappingImpl(Method[] m,
String finderName,
String append)
throws Exception
{
// Adrian Brock: This should go away when we don't support EJB1x
boolean isEJB1x = metaData.getApplicationMetaData().isEJB1x();
for (int i = 0; i < m.length; i++)
{
String methodName = m[i].getName();
try
{
try // Try home method
{
String ejbHomeMethodName = "ejbHome" + methodName.substring(0,1).toUpperCase() + methodName.substring(1);
homeMapping.put(m[i], beanClass.getMethod(ejbHomeMethodName, m[i].getParameterTypes()));
continue;
}
catch (NoSuchMethodException ignore) {} // just go on with other types of methods
// Implemented by container (in both cases)
if (methodName.startsWith("find"))
{
homeMapping.put(m[i], this.getClass().getMethod(finderName, new Class[] { Invocation.class }));
}
else if (methodName.equals("create") ||
(isEJB1x == false && methodName.startsWith("create")))
{
homeMapping.put(m[i], this.getClass().getMethod("create"+append, new Class[] { Invocation.class }));
beanMapping.put(m[i], this.getClass().getMethod("postCreate"+append, new Class[] { Invocation.class }));
}
else
{
homeMapping.put(m[i], this.getClass().getMethod(methodName+append, new Class[] { Invocation.class }));
}
}
catch (NoSuchMethodException e)
{
throw new NoSuchMethodException("Could not find matching method for "+m[i]);
}
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void setupHomeMapping() throws Exception
{
try {
if (homeInterface != null)
{
Method[] m = homeInterface.getMethods();
setupHomeMappingImpl( m, "find", "Home" );
}
if (localHomeInterface != null)
{
Method[] m = localHomeInterface.getMethods();
setupHomeMappingImpl( m, "findLocal", "LocalHome" );
}
// Special methods
// Get the One on Handle (getEJBObject), get the class
Class handleClass = Class.forName("javax.ejb.Handle");
// Get the methods (there is only one)
Method[] handleMethods = handleClass.getMethods();
//Just to make sure let's iterate
for (int j=0; j<handleMethods.length ;j++)
{
//Get only the one called handle.getEJBObject
if (handleMethods[j].getName().equals("getEJBObject"))
{
//Map it in the home stuff
homeMapping.put(handleMethods[j],
this.getClass().getMethod("getEJBObject",
new Class[] {Invocation.class}));
}
}
}
catch (Exception e)
{
// ditch the half built mappings
homeMapping.clear();
beanMapping.clear();
throw e;
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
private void setupBeanMappingImpl( Method[] m, String intfName )
throws Exception
{
for (int i = 0; i < m.length; i++)
{
if (!m[i].getDeclaringClass().getName().equals(intfName))
{
// Implemented by bean
beanMapping.put(m[i], beanClass.getMethod(m[i].getName(), m[i].getParameterTypes()));
}
else
{
// Implemented by container
beanMapping.put(m[i], getClass().getMethod(m[i].getName(),
new Class[] { Invocation.class }));
}
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void setupBeanMapping() throws Exception
{
try {
if (remoteInterface != null)
{
Method[] m = remoteInterface.getMethods();
setupBeanMappingImpl( m, "javax.ejb.EJBObject" );
}
if (localInterface != null)
{
Method[] m = localInterface.getMethods();
setupBeanMappingImpl( m, "javax.ejb.EJBLocalObject" );
}
if( TimedObject.class.isAssignableFrom( beanClass ) ) {
// Map ejbTimeout
beanMapping.put(
TimedObject.class.getMethod( "ejbTimeout", new Class[] { Timer.class } ),
beanClass.getMethod( "ejbTimeout", new Class[] { Timer.class } )
);
}
}
catch (Exception e)
{
// ditch the half built mappings
homeMapping.clear();
beanMapping.clear();
throw e;
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void setupMarshalledInvocationMapping() throws Exception
{
// Create method mappings for container invoker
if (homeInterface != null)
{
Method [] m = homeInterface.getMethods();
for (int i = 0 ; i<m.length ; i++)
{
marshalledInvocationMapping.put( new Long(MarshalledInvocation.calculateHash(m[i])), m[i]);
}
}
if (remoteInterface != null)
{
Method [] m = remoteInterface.getMethods();
for (int j = 0 ; j<m.length ; j++)
{
marshalledInvocationMapping.put( new Long(MarshalledInvocation.calculateHash(m[j])), m[j]);
}
}
// Get the getEJBObjectMethod
Method getEJBObjectMethod = Class.forName("javax.ejb.Handle").getMethod("getEJBObject", new Class[0]);
// Hash it
marshalledInvocationMapping.put(new Long(MarshalledInvocation.calculateHash(getEJBObjectMethod)),getEJBObjectMethod);
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
protected void checkCoherency () throws Exception
{
// Check clustering cohrency wrt metadata
//
if (metaData.isClustered())
{
boolean clusteredProxyFactoryFound = false;
for (Iterator it = proxyFactories.keySet().iterator(); it.hasNext(); )
{
String invokerBinding = (String)it.next();
EJBProxyFactory ci = (EJBProxyFactory)proxyFactories.get(invokerBinding);
if (ci instanceof org.jboss.proxy.ejb.ClusterProxyFactory)
clusteredProxyFactoryFound = true;
}
if (!clusteredProxyFactoryFound)
{
log.warn("*** EJB '" + this.metaData.getEjbName() + "' deployed as CLUSTERED but not a single clustered-invoker is bound to container ***");
}
}
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
private Object findSingleObject(Transaction tx,
Method method,
Object[] args,
EntityEnterpriseContext instance,
GenericEntityObjectFactory factory)
throws Exception
{
if(method.getName().equals("findByPrimaryKey"))
{
if(args[0] == null)
throw new IllegalArgumentException("findByPrimaryKey called with null argument.");
if(metaData.getContainerConfiguration().getCommitOption() != ConfigurationMetaData.B_COMMIT_OPTION)
{
Object key = instance.getCacheKey();
if(key == null)
{
key = ((EntityCache)instanceCache).createCacheKey(args[0]);
}
if(instanceCache.isActive(key))
{
return factory.getEntityEJBObject(key);
}
}
}
else if(!metaData.getContainerConfiguration().getSyncOnCommitOnly())
{
EntityContainer.synchronizeEntitiesWithinTransaction(tx);
}
return getPersistenceManager().findEntity(method, args, instance, factory);
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object invokeHome(Invocation mi) throws Exception
{
// Invoke and handle exceptions
Method miMethod = mi.getMethod();
Method m = (Method) homeMapping.get(miMethod);
if( m == null )
{
String msg = "Invalid invocation, check your deployment packaging"
+", method="+miMethod;
throw new EJBException(msg);
}
if (m.getDeclaringClass().equals(EntityContainer.class))
{
try
{
return mi.performCall(EntityContainer.this, m, new Object[] { mi });
}
catch (Exception e)
{
rethrow(e);
}
}
else // Home method
{
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
try
{
AllowedOperationsAssociation.pushInMethodFlag(AllowedOperationsAssociation.IN_EJB_HOME);
return mi.performCall(ctx.getInstance(), m, mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
finally{
AllowedOperationsAssociation.popInMethodFlag();
}
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/ejb/EntityContainer.java
public Object invoke(Invocation mi) throws Exception
{
// Get method
Method miMethod = mi.getMethod();
Method m = (Method) beanMapping.get(miMethod);
if( m == null )
{
String msg = "Invalid invocation, check your deployment packaging"
+", method="+miMethod;
throw new EJBException(msg);
}
// Select instance to invoke (container or bean)
if (m.getDeclaringClass().equals(EntityContainer.class))
{
// Invoke container
try
{
return mi.performCall(EntityContainer.this, m, new Object[]{ mi });
}
catch (Exception e)
{
rethrow(e);
}
}
else
{
// Invoke bean instance
try
{
EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext();
Object instance = ctx.getInstance();
return mi.performCall(instance, m, mi.getArguments());
}
catch (Exception e)
{
rethrow(e);
}
}
// We will never get this far, but the compiler does not know that
throw new org.jboss.util.UnreachableStatementException();
}
// in src/main/java/org/jboss/Shutdown.java
public static void main(final String[] args) throws Exception
{
if (args.length == 0)
{
displayUsage();
System.exit(0);
}
String sopts = "-:hD:s:n:a:u:p:S::v::o:r:";
LongOpt[] lopts =
{
new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'),
new LongOpt("server", LongOpt.REQUIRED_ARGUMENT, null, 's'),
new LongOpt("adapter", LongOpt.REQUIRED_ARGUMENT, null, 'a'),
new LongOpt("serverName", LongOpt.REQUIRED_ARGUMENT, null, 'n'),
new LongOpt("shutdown", LongOpt.NO_ARGUMENT, null, 'S'),
new LongOpt("user", LongOpt.REQUIRED_ARGUMENT, null, 'u'),
new LongOpt("verbose", LongOpt.NO_ARGUMENT, null, 'v'),
new LongOpt("password", LongOpt.REQUIRED_ARGUMENT, null, 'p'),
new LongOpt("host", LongOpt.REQUIRED_ARGUMENT, null, 'o'),
new LongOpt("port", LongOpt.REQUIRED_ARGUMENT, null, 'r'),
};
Getopt getopt = new Getopt(PROGRAM_NAME, args, sopts, lopts);
int code;
String arg;
String serverURL = null;
String username = null;
String password = null;
ObjectName serverJMXName = new ObjectName("jboss.system:type=Server");
String hostname=null;
String port=null;
boolean verbose = false;
while ((code = getopt.getopt()) != -1)
{
switch (code)
{
case ':':
case '?':
// for now both of these should exit with error status
System.exit(1);
break;
case 1:
// this will catch non-option arguments
// (which we don't currently care about)
System.err.println(PROGRAM_NAME + ": unused non-option argument: " +
getopt.getOptarg());
break;
case 'h':
displayUsage();
System.exit(0);
break;
case 'D':
{
// set a system property
arg = getopt.getOptarg();
String name, value;
int i = arg.indexOf("=");
if (i == -1)
{
name = arg;
value = "true";
}
else
{
name = arg.substring(0, i);
value = arg.substring(i + 1, arg.length());
}
System.setProperty(name, value);
break;
}
case 's':
serverURL = getopt.getOptarg();
break;
case 'n':
serverJMXName = new ObjectName(getopt.getOptarg());
break;
case 'S':
// nothing...
break;
case 'a':
String adapterName = getopt.getOptarg();
System.out.println("adapter name is ignored " + adapterName);
break;
case 'u':
username = getopt.getOptarg();
break;
case 'p':
password = getopt.getOptarg();
break;
// host name
case 'o':
hostname = getopt.getOptarg();
break;
// host port
case 'r':
port = getopt.getOptarg();
break;
// be noisy
case 'v':
verbose = true;
break;
}
}
// If there was a username specified, but no password prompt for it
if( username != null && password == null )
{
System.out.print("Enter password for "+username+": ");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
password = br.readLine();
}
if( serverURL == null)
{
serverURL = DEFAULT_BASEURL +
(hostname != null ? hostname : DEFAULT_HOSTNAME) +
":" +
(port != null ? port : DEFAULT_PORT) +
DEFAULT_RMIOBJECTNAME;
}
if( verbose )
{
System.out.println("JMX server url=" + serverURL);
}
HashMap env = new HashMap();
if (username != null && password != null)
{
if (verbose )
{
System.out.println("will connect with username=" + username);
}
String[] creds = new String[2];
creds[0] = username;
creds[1] = password;
env.put(JMXConnector.CREDENTIALS, creds);
}
JMXServiceURL url = new JMXServiceURL(serverURL);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
MBeanServerConnection adaptor = jmxc.getMBeanServerConnection();
ServerProxyHandler handler = new ServerProxyHandler(adaptor, serverJMXName);
Class<?>[] ifaces = {JBossASServer.class};
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
JBossASServer server = (JBossASServer) Proxy.newProxyInstance(tcl, ifaces, handler);
server.shutdown();
System.out.println("Shutdown message has been posted to the server.");
System.out.println("Server shutdown may take a while - check logfiles for completion");
jmxc.close();
}
// in src/main/java/org/jboss/cache/invalidation/InvalidationsTxGrouper.java
public static void registerInvalidationSynchronization(Transaction tx, InvalidationGroup group, Serializable key)
throws Exception
{
InvalidatorSynchronization synch = (InvalidatorSynchronization) synchLocal.get(tx);
if(synch == null)
{
synch = new InvalidatorSynchronization(tx);
synchLocal.set(tx, synch);
// If there is no tx don't try to use it
if( tx != null )
tx.registerSynchronization(synch);
}
synch.addInvalidation(group, key);
// If there is no tx call afterCompletion
if( tx == null )
synch.afterCompletion(javax.transaction.Status.STATUS_NO_TRANSACTION);
}
// in src/main/java/org/jboss/cache/invalidation/triggers/EntityBeanCacheBatchInvalidatorInterceptor.java
public void start() throws Exception
{
org.jboss.metadata.EntityMetaData emd = ((org.jboss.metadata.EntityMetaData)this.getContainer ().getBeanMetaData ());
doCacheInvalidations = emd.doDistributedCacheInvalidations ();
if (doCacheInvalidations)
{
// we are interested in receiving cache invalidation callbacks
//
String groupName = emd.getDistributedCacheInvalidationConfig ().getInvalidationGroupName ();
String imName = emd.getDistributedCacheInvalidationConfig ().getInvalidationManagerName ();
this.invalMgr = (org.jboss.cache.invalidation.InvalidationManagerMBean)org.jboss.system.Registry.lookup (imName);
this.ig = this.invalMgr.getInvalidationGroup (groupName);
}
}
// in src/main/java/org/jboss/cache/invalidation/triggers/EntityBeanCacheBatchInvalidatorInterceptor.java
protected boolean changed (org.jboss.invocation.Invocation mi, org.jboss.ejb.EntityEnterpriseContext ctx) throws Exception
{
if (ctx.getId() == null) return true;
if(!container.isReadOnly())
{
java.lang.reflect.Method method = mi.getMethod();
if(method == null ||
!container.getBeanMetaData().isMethodReadOnly(method.getName()))
{
return invalidateRelated ?
container.getPersistenceManager().isModified(ctx) :
container.getPersistenceManager().isStoreRequired(ctx);
}
}
return false;
}
// in src/main/java/org/jboss/cache/invalidation/triggers/EntityBeanCacheBatchInvalidatorInterceptor.java
public Object invoke(org.jboss.invocation.Invocation mi) throws Exception
{
if (doCacheInvalidations)
{
// We are going to work with the context a lot
org.jboss.ejb.EntityEnterpriseContext ctx = (org.jboss.ejb.EntityEnterpriseContext)mi.getEnterpriseContext();
Object id = ctx.getId();
// The Tx coming as part of the Method Invocation
javax.transaction.Transaction tx = mi.getTransaction();
// Invocation with a running Transaction
if (tx != null && tx.getStatus() != javax.transaction.Status.STATUS_NO_TRANSACTION)
{
//Invoke down the chain
Object retVal = getNext().invoke(mi);
if (changed(mi, ctx))
{
org.jboss.cache.invalidation.InvalidationsTxGrouper.registerInvalidationSynchronization (tx, this.ig, (java.io.Serializable)id);
}
// return the return value
return retVal;
}
//
else
{ // No tx
Object result = getNext().invoke(mi);
if (changed(mi, ctx))
{
org.jboss.cache.invalidation.InvalidationsTxGrouper.registerInvalidationSynchronization (tx, this.ig, (java.io.Serializable)id);
}
return result;
}
}
else
{
return getNext().invoke(mi);
}
}
// in src/main/java/org/jboss/cache/invalidation/triggers/EntityBeanCacheBatchInvalidatorInterceptor.java
public void importXml(Element element) throws Exception
{
String str = MetaData.getElementAttribute(element, "invalidate-related");
invalidateRelated = (str == null ? true : Boolean.valueOf(str).booleanValue());
if(log.isTraceEnabled())
{
log.trace("invalidate-related: " + invalidateRelated);
}
}
// in src/main/java/org/jboss/cache/invalidation/bridges/JMSCacheInvalidationBridge.java
protected void startService () throws Exception
{
log.info("Starting JMS cache invalidation bridge");
// Deal with the InvalidationManager first..
//
this.invalMgr = (org.jboss.cache.invalidation.InvalidationManagerMBean)
org.jboss.system.Registry.lookup (this.invalidationManagerName);
this.invalidationSubscription = invalMgr.registerBridgeListener (this);
// deal with JMS next
//
InitialContext iniCtx = getInitialContext ();
Object tmp = iniCtx.lookup(this.connectionFactoryName);
TopicConnectionFactory tcf = (TopicConnectionFactory) tmp;
conn = tcf.createTopicConnection();
topic = (Topic) iniCtx.lookup(this.topicName);
session = conn.createTopicSession(this.transacted,
this.acknowledgeMode);
conn.start();
// Are we publisher, subscriber, or both?
//
if (this.propagationMode == JMSCacheInvalidationBridgeMBean.IN_OUT_BRIDGE_PROPAGATION ||
this.propagationMode == JMSCacheInvalidationBridgeMBean.IN_ONLY_BRIDGE_PROPAGATION)
{
this.subscriber = session.createSubscriber(topic);
this.subscriber.setMessageListener(this);
}
if (this.propagationMode == JMSCacheInvalidationBridgeMBean.IN_OUT_BRIDGE_PROPAGATION ||
this.propagationMode == JMSCacheInvalidationBridgeMBean.OUT_ONLY_BRIDGE_PROPAGATION)
{
this.pub = session.createPublisher(topic);
this.publishingAuthorized = true;
}
}
// in src/main/java/org/jboss/cache/invalidation/InvalidationManager.java
public void startService () throws Exception
{
// bind us in system registry
//
log.debug ("Starting Invalidation Manager " + this.getServiceName ().toString ());
org.jboss.system.Registry.bind (this.getServiceName ().toString (), this);
this.hashcode = this.getServiceName ().hashCode ();
}
// in src/main/java/org/jboss/monitor/BeanCacheMonitor.java
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception
{
m_mbeanServer = server;
return name;
}
// in src/main/java/org/jboss/monitor/BeanCacheMonitor.java
public void preDeregister() throws Exception
{}
// in src/main/java/org/jboss/monitor/EntityLockMonitor.java
protected void startService()
throws Exception
{
bind();
log.info("EntityLockMonitor started");
}
// in src/main/java/org/jboss/web/WebServer.java
public void start() throws Exception
{
if (executor == null)
throw new IllegalArgumentException("Required property 'executor' not specified");
try
{
server = new ServerSocket(port, backlog, bindAddress);
log.debug("Started server: " + server);
listen();
}
catch(java.net.BindException be)
{
throw new Exception("Port "+port+" already in use.",be);
}
catch (IOException e)
{
throw e;
}
}
// in src/main/java/org/jboss/web/deployers/AbstractWarDeployment.java
public synchronized WebApplication start(DeploymentUnit unit, JBossWebMetaData metaData) throws Exception
{
Thread thread = Thread.currentThread();
ClassLoader appClassLoader = thread.getContextClassLoader();
WebApplication webApp = null;
try
{
// Create a classloader for the war to ensure a unique ENC
ClassLoader warLoader = unit.getClassLoader();
thread.setContextClassLoader(warLoader);
String webContext = metaData.getContextRoot();
// Get the war URL
URL warUrl = unit.getAttachment("org.jboss.web.expandedWarURL", URL.class);
if (warUrl == null && unit instanceof VFSDeploymentUnit)
{
VFSDeploymentUnit vdu = VFSDeploymentUnit.class.cast(unit);
warUrl = VFSUtils.getPhysicalURL(vdu.getRoot());
}
// Dynamic WebMetaData deployments might not provide an URL
// We use the DEploymentUnit name as identifier instead.
// The JAXWS Endpoint API for example does this.
String warURLString = (warUrl != null ? warUrl.toExternalForm() : unit.getName());
// Strip any jar: url syntax. This should be be handled by the vfs
if (warURLString.startsWith("jar:"))
warURLString = warURLString.substring(4, warURLString.length() - 2);
log.debug("webContext: " + webContext);
log.debug("warURL: " + warURLString);
// Register the permissions with the JACC layer
String contextID = metaData.getJaccContextID();
if (contextID == null)
contextID = unit.getSimpleName();
metaData.setJaccContextID(contextID);
webApp = new WebApplication(metaData);
webApp.setClassLoader(warLoader);
webApp.setDeploymentUnit(unit);
performDeploy(webApp, warURLString);
}
finally
{
thread.setContextClassLoader(appClassLoader);
}
return webApp;
}
// in src/main/java/org/jboss/web/deployers/AbstractWarDeployment.java
public synchronized void stop(DeploymentUnit di, WebApplication webApp) throws Exception
{
URL warURL = webApp.getURL();
String warUrl = warURL.toString();
performUndeploy(webApp, warUrl);
}
// in src/main/java/org/jboss/web/deployers/AbstractWarDeployment.java
protected void processEnc(ClassLoader loader, WebApplication webApp) throws Exception
{
if (loader == null)
throw new IllegalArgumentException("Classloader passed to process ENC refs is null");
log.debug("AbstractWebContainer.parseWebAppDescriptors, Begin");
InitialContext iniCtx = new InitialContext();
Context envCtx = null;
Thread currentThread = Thread.currentThread();
ClassLoader currentLoader = currentThread.getContextClassLoader();
JBossWebMetaData metaData = webApp.getMetaData();
try
{
// Create a java:comp/env environment unique for the web application
log.debug("Creating ENC using ClassLoader: " + loader);
ClassLoader parent = loader.getParent();
while (parent != null)
{
log.debug(".." + parent);
parent = parent.getParent();
}
// TODO: The enc should be an input?
currentThread.setContextClassLoader(loader);
// webApp.setENCLoader(loader);
envCtx = (Context)iniCtx.lookup("java:comp");
// TODO: inject the ORB
try
{
ObjectName ORB_NAME = new ObjectName("jboss:service=CorbaORB");
org.omg.CORBA.ORB orb = (org.omg.CORBA.ORB)server.getAttribute(ORB_NAME, "ORB");
// Bind the orb
if (orb != null)
{
NonSerializableFactory.rebind(envCtx, "ORB", orb);
log.debug("Bound java:comp/ORB");
}
}
catch (Throwable t)
{
log.debug("Unable to retrieve orb" + t.toString());
}
// TODO: injection, Add a link to the global transaction manager
envCtx.bind("UserTransaction", new LinkRef("UserTransaction"));
log.debug("Linked java:comp/UserTransaction to JNDI name: UserTransaction");
envCtx = envCtx.createSubcontext("env");
processEncReferences(webApp, envCtx);
}
finally
{
currentThread.setContextClassLoader(currentLoader);
}
String securityDomain = metaData.getSecurityDomain();
log.debug("linkSecurityDomain");
linkSecurityDomain(securityDomain, envCtx);
log.debug("AbstractWebContainer.parseWebAppDescriptors, End");
}
// in src/main/java/org/jboss/web/deployers/FacesConfigParsingDeployer.java
Override
protected JSFDeployment parse(DeploymentUnit unit, String name, JSFDeployment output) throws Exception {
if (unit instanceof VFSDeploymentUnit == false) {
return null;
}
if (ignoreName(unit, name)) {
return null;
}
VFSDeploymentUnit vfsDeploymentUnit = (VFSDeploymentUnit) unit;
List<VirtualFile> facesConfigXmlFiles = vfsDeploymentUnit.getMetaDataFiles(new FacesConfigXmlFileNameMatchFilter(), MetaDataTypeFilter.ALL);
if (facesConfigXmlFiles == null || facesConfigXmlFiles.isEmpty()) {
return null;
}
JSFDeployment jsfDeployment = vfsDeploymentUnit.getAttachment(JSFDeployment.class);
for (VirtualFile facesConfigXmlFile : facesConfigXmlFiles) {
if (this.ignoreFile(vfsDeploymentUnit, facesConfigXmlFile)) {
continue;
}
jsfDeployment = this.parse(vfsDeploymentUnit, facesConfigXmlFile, jsfDeployment);
}
return jsfDeployment;
}
// in src/main/java/org/jboss/web/deployers/FacesConfigParsingDeployer.java
Override
protected JSFDeployment parse(VFSDeploymentUnit unit, VirtualFile file, JSFDeployment jsfDeployment) throws Exception {
URL facesConfigURL = file.toURL();
if (jsfDeployment == null) {
// create the jsf deployment. Note that we don't have to attach it to the deployment unit, since that part
// will be done by the AbstractVFSParsingDeployer which will attach the return value of this method to the unit.
jsfDeployment = new JSFDeployment();
}
// parse the xml file and update the jsf deployment
FacesConfigParsingUtil.parse(unit, facesConfigURL, jsfDeployment);
// return the updated jsf deployment
return jsfDeployment;
}
// in src/main/java/org/jboss/web/deployers/WebModule.java
public void start() throws Exception
{
startModule();
}
// in src/main/java/org/jboss/web/deployers/WebModule.java
public void stop() throws Exception
{
stopModule();
}
// in src/main/java/org/jboss/web/deployers/WebModule.java
public synchronized void startModule() throws Exception
{
if (this.unit == null || this.container == null || this.deployment == null)
throw new IllegalStateException("WebModules cannot be restarted, and must be redeployed");
// Get the war URL
JBossWebMetaData metaData = unit.getAttachment(JBossWebMetaData.class);
WebApplication webApp = deployment.start(unit, metaData);
String warURL = unit.getName();
container.addDeployedApp(warURL, webApp);
}
// in src/main/java/org/jboss/web/deployers/AbstractWarDeployer.java
public void start() throws Exception
{
// TODO: remove dependency on jmx
this.server = MBeanServerLocator.locateJBoss();
}
// in src/main/java/org/jboss/web/deployers/AbstractWarDeployer.java
public void stop() throws Exception
{
}
// in src/main/java/org/jboss/web/deployers/AbstractWarDeployer.java
protected void deployWebModule(DeploymentUnit unit, JBossWebMetaData metaData, AbstractWarDeployment deployment) throws Exception
{
log.debug("deployWebModule: " + unit.getName());
try
{
ServiceMetaData webModule = new ServiceMetaData();
String name = getObjectName(metaData);
ObjectName objectName = new ObjectName(name);
webModule.setObjectName(objectName);
webModule.setCode(WebModule.class.getName());
// WebModule(DeploymentUnit, AbstractWarDeployer, AbstractWarDeployment)
ServiceConstructorMetaData constructor = new ServiceConstructorMetaData();
constructor.setSignature(new String[] { DeploymentUnit.class.getName(), AbstractWarDeployer.class.getName(), AbstractWarDeployment.class.getName() });
constructor.setParameters(new Object[] { unit, this, deployment });
webModule.setConstructor(constructor);
List<ServiceAttributeMetaData> attrs = new ArrayList<ServiceAttributeMetaData>();
ServiceAttributeMetaData attr = new ServiceAttributeMetaData();
attr.setName("SecurityManagement");
ServiceInjectionValueMetaData injectionValue = new ServiceInjectionValueMetaData(deployment.getSecurityManagementName());
attr.setValue(injectionValue);
attrs.add(attr);
ServiceAttributeMetaData attrPR = new ServiceAttributeMetaData();
attrPR.setName("PolicyRegistration");
ServiceInjectionValueMetaData injectionValuePR = new ServiceInjectionValueMetaData(deployment.getPolicyRegistrationName());
attrPR.setValue(injectionValuePR);
attrs.add(attrPR);
ServiceAttributeMetaData attrKernel = new ServiceAttributeMetaData();
attrKernel.setName("Kernel");
ServiceInjectionValueMetaData injectionValueKernel = new ServiceInjectionValueMetaData(KernelConstants.KERNEL_NAME);
attrKernel.setValue(injectionValueKernel);
attrs.add(attrKernel);
webModule.setAttributes(attrs);
// Dependencies...Still have old jmx names here
Collection<String> depends = metaData.getDepends();
List<ServiceDependencyMetaData> dependencies = new ArrayList<ServiceDependencyMetaData>();
if (depends != null && depends.isEmpty() == false)
{
if (log.isTraceEnabled())
log.trace(name + " has dependencies: " + depends);
for (String iDependOn : depends)
{
ServiceDependencyMetaData sdmd = new ServiceDependencyMetaData();
sdmd.setIDependOn(iDependOn);
dependencies.add(sdmd);
}
}
// SwitchBoard
Barrier switchBoard = unit.getAttachment(Barrier.class);
if (switchBoard != null)
{
// Setup switchboard dependency on the deployment
ServiceDependencyMetaData switchBoardDependency = new AnyStateServiceDependencyMetaData(switchBoard.getId(), ControllerState.START, ControllerState.INSTALLED);
dependencies.add(switchBoardDependency);
log.debug("Added switchboard dependency: " + switchBoard.getId() + " for web module: " + name);
}
// Injection Manager
InjectionManager injectionManager = unit.getAttachment(InjectionManager.class);
if (injectionManager != null)
{
// set the InjectionManager on the deployment
deployment.setInjectionManager(injectionManager);
// Setup the Injector
Environment webEnvironment = metaData.getJndiEnvironmentRefsGroup();
if (webEnvironment != null)
{
// convert JBMETA metadata to jboss-injection specific metadata
JndiEnvironmentRefsGroup jndiEnvironment = new JndiEnvironmentImpl(webEnvironment, unit.getClassLoader());
// For optimization, we'll create an Injector only if there's atleast one InjectionTarget
if (this.hasInjectionTargets(jndiEnvironment))
{
// create the injector
EEInjector eeInjector = new EEInjector(jndiEnvironment);
// add the injector the injection manager
injectionManager.addInjector(eeInjector);
// Deploy the Injector as a MC bean (so that the fully populated naming context (obtained via the SwitchBoard
// Barrier) gets injected.
String injectorMCBeanName = this.getInjectorMCBeanName(unit);
BeanMetaData injectorBMD = this.createInjectorBMD(injectorMCBeanName, eeInjector, switchBoard);
unit.addAttachment(BeanMetaData.class + ":" + injectorMCBeanName, injectorBMD);
// Add the Injector dependency on the deployment (so that the DU doesn't
// get started till the Injector is available)
ServiceDependencyMetaData injectorDepdendency = new ServiceDependencyMetaData();
injectorDepdendency.setIDependOn(injectorMCBeanName);
dependencies.add(injectorDepdendency);
log.debug("Added Injector dependency: " + injectorMCBeanName + " for web module: " + name);
}
}
}
// TODO: We haven't yet integrated PC and EJB reference providers in SwitchBoard.
// The following sections will be removed after the RPs are made available
// JBAS-6795 Add dependency on PersistenceContext references
PersistenceContextReferencesMetaData pcRefs = metaData.getPersistenceContextRefs();
if (pcRefs != null)
{
for (PersistenceContextReferenceMetaData pcRef : metaData.getPersistenceContextRefs())
{
// TODO: this is a duplication of the logic in PersistenceContextHandler
String persistenceUnitName = pcRef.getPersistenceUnitName();
String beanName = persistenceUnitDependencyResolver.resolvePersistenceUnitSupplier(unit, persistenceUnitName);
ServiceDependencyMetaData sdmd = new ServiceDependencyMetaData();
sdmd.setIDependOn(beanName);
dependencies.add(sdmd);
}
}
webModule.setDependencies(dependencies);
// Here's where a bit of magic happens. By attaching the ServiceMetaData
// to the deployment, we now make the deployment "relevant" to
// deployers that use ServiceMetaData as an input (e.g. the
// org.jboss.system.deployers.ServiceDeployer). Those deployers
// can now take over deploying the web module.
unit.addAttachment("WarServiceMetaData", webModule, ServiceMetaData.class);
}
catch (Exception e)
{
throw DeploymentException.rethrowAsDeploymentException("Error creating web module " + unit.getName(), e);
}
}
// in src/main/java/org/jboss/web/deployers/WarAnnotationMetaDataDeployer.java
protected void processMetaData(VFSDeploymentUnit unit, List<VirtualFile> classpath) throws Exception
{
ResourcesIndex ri = unit.getAttachment(ResourcesIndex.class);
if (ri == null)
{
return;
}
AnnotationFinder<AnnotatedElement> finder = new DefaultAnnotationFinder<AnnotatedElement>();
Web30MetaDataCreator creator = new Web30MetaDataCreator(finder);
// Merge processed annotations from all scopes
Set<Class<? extends Annotation>> annotations = new HashSet<Class<? extends Annotation>>();
AnnotationContext annotationContext = creator.getAnnotationContext();
if (annotationContext.getTypeAnnotations() != null)
annotations.addAll(annotationContext.getTypeAnnotations());
if (annotationContext.getMethodAnnotations() != null)
annotations.addAll(annotationContext.getMethodAnnotations());
if (annotationContext.getFieldAnnotations() != null)
annotations.addAll(annotationContext.getFieldAnnotations());
boolean metaData = false;
for (VirtualFile path : classpath)
{
Set<Class<?>> annotatedClasses = new HashSet<Class<?>>();
for (Class<? extends Annotation> annotation : annotations)
{
annotatedClasses.addAll(ri.getAnnotatedClasses(path, annotation));
}
WebMetaData annotationMetaData = creator.create(annotatedClasses);
if (annotationMetaData != null)
{
unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME + ":" + path.getName(), annotationMetaData, WebMetaData.class);
metaData = true;
}
}
if (metaData)
unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME, Boolean.TRUE);
}
// in src/main/java/org/jboss/web/deployers/WebContextParamFacesConfigParsingDeployer.java
private void processConfigFilesContextParamValue(final VFSDeploymentUnit vfsDeploymentUnit, final JSFDeployment jsfDeployment, final String configFilesContextParamValue) throws Exception
{
if (configFilesContextParamValue == null)
{
return;
}
// trim the context param value
String trimmedConfigParamValues = configFilesContextParamValue.trim();
// split the paths which are separated by "," delimiter
String[] paths = trimmedConfigParamValues.split(",");
for (String path : paths)
{
// trim each path
path = path.trim();
if (path.isEmpty())
{
continue;
}
// skip this path, since .war/WEB-INF/faces-config.xml is by default parsed
// (by a separate deployer)
if (WEB_INF_FACES_CONFIG_XML.equals(path))
{
continue;
}
// get hold of the file relative to the deployment unit root
VirtualFile facesConfigXml = vfsDeploymentUnit.getRoot().getChild(path);
// for a file which wasn't found, just log a WARN and move on to the next
if (facesConfigXml == null)
{
logger.warn("Faces config xml not found at relative path: " + path + " in unit " + vfsDeploymentUnit.getRoot());
continue;
}
logger.debug("Found faces config xml with relative path: " + path + " in unit " + vfsDeploymentUnit.getRoot());
// parse the faces config file
FacesConfigParsingUtil.parse(vfsDeploymentUnit, facesConfigXml.toURL(), jsfDeployment);
}
}
// in src/main/java/org/jboss/web/deployers/FacesConfigParsingUtil.java
public static void parse(final DeploymentUnit unit, final URL facesConfigXmlURL, final JSFDeployment jsfDeployment) throws Exception
{
logger.debug("Checking for the presence of JSF managed-bean(s) in JSF config file: " + facesConfigXmlURL + " in deployment unit: " + unit);
// get the parser factory
SAXParserFactory parserFactory = getParserFactory();
// create a parser
SAXParser saxParser = parserFactory.newSAXParser();
InputStream inputStream = null;
try
{
// get the input stream and the input source for the faces config file
inputStream = getInputStream(facesConfigXmlURL);
InputSource inputSource = new InputSource(getInputStream(facesConfigXmlURL));
inputSource.setSystemId(facesConfigXmlURL.toExternalForm());
// parse it!
saxParser.parse(inputSource, new DefaultHandler()
{
/**
* Flag to keep track of managed-bean-class element being processed
*/
private boolean managedBeanClassElementProcessingInProgress;
/**
* Uses the {@link JBossEntityResolver} to resolve the entity. If it cannot be resolved by the {@link JBossEntityResolver}
* then this method lets the {@link DefaultHandler} to resolve it.
*
* @param publicId
* @param systemId
* @return
* @throws IOException
* @throws SAXException
*/
@Override
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException
{
// try resolving it with the JBossEntityResolver
InputSource source = jBossJSFEntityResolver.resolveEntity(publicId, systemId);
if (source != null)
{
return source;
}
// we couldn't resolve, so let the default handler try to resolve it
return super.resolveEntity(publicId, systemId);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
{
// we are only interested in managed-bean-class element.
if (localName.equals("managed-bean-class"))
{
this.managedBeanClassElementProcessingInProgress = true;
}
// let the super do its job
super.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
// reset the flag when the managed-bean-class element ends
if (localName.equals("managed-bean-class"))
{
this.managedBeanClassElementProcessingInProgress = false;
}
// let super do its job
super.endElement(uri, localName, qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException
{
// if we are currently processing the managed-bean-class element, then fetch the managed bean
// class name text
if (this.managedBeanClassElementProcessingInProgress)
{
// get the managed bean class name
String managedBeanClassName = new String(ch, start, length);
if (!managedBeanClassName.trim().isEmpty())
{
logger.debug("Found JSF managed bean class: " + managedBeanClassName + " in unit " + unit);
// add it to the jsf deployment
jsfDeployment.addManagedBean(managedBeanClassName);
}
}
// let super do its job now
super.characters(ch, start, length);
}
});
}
finally
{
if (inputStream != null)
{
inputStream.close();
}
}
return;
}
// in src/main/java/org/jboss/web/deployers/SpecCompliantWarAnnotationDeployer.java
Override
protected void processMetaData(VFSDeploymentUnit unit, List<VirtualFile> classpath) throws Exception
{
ResourcesIndex resourceIndex = unit.getAttachment(ResourcesIndex.class);
if (resourceIndex == null)
{
return;
}
AnnotationFinder<AnnotatedElement> finder = new DefaultAnnotationFinder<AnnotatedElement>();
Web30MetaDataCreator creator = new Web30MetaDataCreator(finder);
// Merge processed annotations from all scopes
Set<Class<? extends Annotation>> annotations = new HashSet<Class<? extends Annotation>>();
AnnotationContext annotationContext = creator.getAnnotationContext();
if (annotationContext.getTypeAnnotations() != null)
annotations.addAll(annotationContext.getTypeAnnotations());
if (annotationContext.getMethodAnnotations() != null)
annotations.addAll(annotationContext.getMethodAnnotations());
if (annotationContext.getFieldAnnotations() != null)
annotations.addAll(annotationContext.getFieldAnnotations());
Collection<Class<?>> specEligibleResourceInjectionClasses = this.getResourceInjectionEligibleWebAppClasses(resourceIndex, classpath);
boolean metaData = false;
final JSFDeployment jsfDeployment = unit.getAttachment(JSFDeployment.class);
final ManagedBeanDeploymentMetaData managedBeanDeployment = unit.getAttachment(ManagedBeanDeploymentMetaData.class);
for (VirtualFile path : classpath)
{
Collection<Class<?>> eligibleAnnotatedClasses = new HashSet<Class<?>>();
for (Class<? extends Annotation> annotation : annotations)
{
Collection<Class<?>> annotatedClasses = resourceIndex.getAnnotatedClasses(path, annotation);
// include the jsf and Java EE6 managed beans as eligible for resource injection
specEligibleResourceInjectionClasses.addAll(this.getManagedBeansRelatedClasses(jsfDeployment, managedBeanDeployment, annotatedClasses));
// filter out any extra non-spec classes which shouldn't be picked up for resource injection processing
eligibleAnnotatedClasses.addAll(this.retainResourceInjectionEligibleWebAppClasses(specEligibleResourceInjectionClasses, annotatedClasses));
}
WebMetaData annotationMetaData = creator.create(eligibleAnnotatedClasses);
if (annotationMetaData != null)
{
unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME + ":" + path.getName(), annotationMetaData,
WebMetaData.class);
metaData = true;
}
}
if (metaData)
{
unit.addAttachment(WEB_ANNOTATED_ATTACHMENT_NAME, Boolean.TRUE);
}
}
// in src/main/java/org/jboss/web/WebService.java
protected void createService() throws Exception
{
// Load the file mime.types into the mapping list
Properties mimeTypes = new Properties();
try
{
mimeTypes.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("org/jboss/web/mime.types"));
Enumeration keys = mimeTypes.keys();
while (keys.hasMoreElements())
{
String extension = (String) keys.nextElement();
String type = mimeTypes.getProperty(extension);
server.addMimeType(extension, type);
}
}
catch (Exception e)
{
log.error("Failed to load org/jboss/web/mime.types; ignoring", e);
}
// if no override has been specified, default to the jboss bind address
if (getBindAddress() == null)
setBindAddress(System.getProperty(JBossASServerConfig.PROP_KEY_JBOSSAS_BIND_ADDRESS));
// if no host specified, default to the java.rmi.server.hostname property value
if (getHost() == null)
setHost(System.getProperty("java.rmi.server.hostname"));
// Set the rmi codebase if it is not already set
String codebase = getCodebase();
if (codebase == null)
{
// JBAS-8540
codebase = "http://" + ServerConfigUtil.fixHostnameForURL(getHost()) + ":" + getPort() + "/";
System.setProperty("java.rmi.server.codebase", codebase);
}
log.info("Using RMI server codebase: " + codebase);
}
// in src/main/java/org/jboss/web/WebService.java
protected void startService() throws Exception
{
// Start the WebServer running
server.start();
// JBAS-8540
log.debug("Started WebServer with address: " + ServerConfigUtil.fixHostnameForURL(getBindAddress()) + ":" + getPort());
}
// in src/main/java/org/jboss/web/WebService.java
protected void stopService() throws Exception
{
server.stop();
// JBAS-8540
log.debug("Stopped WebServer with address: " + ServerConfigUtil.fixHostnameForURL(getBindAddress()) + ":" + getPort());
}
// in src/main/java/org/jboss/web/WebClassLoaderFactory.java
public static WebClassLoader createWebClassLoader(Class<?> webClassLoaderClass, ObjectName containerName, RealClassLoader parent) throws Exception
{
Constructor constructor = webClassLoaderClass.getConstructor(new Class[]{ObjectName.class, RealClassLoader.class});
return (WebClassLoader) constructor.newInstance(new Object[]{containerName, parent});
}
// in src/main/java/org/jboss/web/RMICodebaseConfigurer.java
Override
protected void startService() throws Exception
{
// Set the rmi codebase if it is not already set
String codebase = System.getProperty("java.rmi.server.codebase");
if (codebase == null)
{
if (host != null)
{
codebase = "http://" + getHostPortion() + getPortPortion() + "/";
System.setProperty("java.rmi.server.codebase", codebase);
}
else
{
getLog().warn("Property codebaseHost has not been set; cannot set java.rmi.server.codebase");
}
}
}
// in src/main/java/org/jboss/proxy/compiler/Runtime.java
void makeProxyType(ProxyCompiler compiler)
throws Exception
{
this.compiler = compiler; // temporary, for use during loading
byte code[] = compiler.getCode();
compiler.proxyType = super.defineClass(compiler.getProxyClassName(), code, 0, code.length);
super.resolveClass(compiler.proxyType);
// set the Foo$Impl.info pointer to myself
Field field = compiler.proxyType.getField(RUNTIME_FN);
field.set(null, this);
compiler = null;
}
// in src/main/java/org/jboss/proxy/compiler/Proxies.java
public static ProxyTarget newTarget(ClassLoader parent,
InvocationHandler invocationHandler,
Class targetTypes[])
throws Exception
{
return Impl.getImpl(targetTypes).newTarget(invocationHandler, parent);
}
// in src/main/java/org/jboss/proxy/compiler/Proxies.java
ProxyTarget newTarget(InvocationHandler invocationHandler,
ClassLoader parent)
throws Exception
{
if (proxyConstructor == null)
{
// make the proxy constructor
ProxyCompiler pc = new ProxyCompiler(parent,
superclass,
targetTypes,
methods);
Class type[] = { InvocationHandler.class };
proxyConstructor = pc.getProxyType().getConstructor(type);
}
Object args[] = { invocationHandler };
return (ProxyTarget)proxyConstructor.newInstance(args);
}
// in src/main/java/org/jboss/proxy/ejb/handle/StatefulHandleImpl.java
protected EJBObject getEjbObjectViaInvoker() throws Exception
{
if (log.isTraceEnabled())
{
log.trace("Using legacy invoker method for getEJBObject() invocation.");
}
SecurityActions sa = SecurityActions.UTIL.getSecurityActions();
Invocation invocation = new Invocation(
null,
GET_EJB_OBJECT,
new Object[]{id},
//No transaction set up in here? it will get picked up in the proxy
null,
// fix for bug 474134 from Luke Taylor
sa.getPrincipal(),
sa.getCredential());
invocation.setObjectName(new Integer(objectName));
invocation.setValue(InvocationKey.INVOKER_PROXY_BINDING,
invokerProxyBinding, PayloadKey.AS_IS);
// It is a home invocation
invocation.setType(InvocationType.HOME);
// Create an invocation context for the invocation
InvocationContext ctx = new InvocationContext();
invocation.setInvocationContext(ctx);
// Get the invoker to the target server (cluster or node)
// Ship it
if (isLocal())
return (EJBObject) InvokerInterceptor.getLocal().invoke(invocation);
else
return (EJBObject) invoker.invoke(invocation);
}
// in src/main/java/org/jboss/proxy/ejb/SecurityActions.java
static SecurityContext createSecurityContext(final Principal p, final Object cred,
final String sdomain) throws Exception
{
return AccessController.doPrivileged(new PrivilegedExceptionAction<SecurityContext>()
{
public SecurityContext run() throws Exception
{
return SecurityContextFactory.createSecurityContext(p,cred, null, sdomain);
}
});
}
// in src/main/java/org/jboss/proxy/ejb/SecurityActions.java
public SecurityContext run() throws Exception
{
return SecurityContextFactory.createSecurityContext(p,cred, null, sdomain);
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
public void create() throws Exception
{
jmxName = container.getJmxName();
jmxNameHash = jmxName.hashCode();
jmxNameHashInteger = new Integer(jmxNameHash);
// Create metadata
BeanMetaData bmd = container.getBeanMetaData();
boolean isSession = !(bmd instanceof EntityMetaData);
boolean isStatelessSession = false;
if(isSession)
{
SessionMetaData smd = (SessionMetaData) bmd;
if(bmd.getRemote() == null)
{
isServiceEndpointOnly = true;
// nothing more to do
return;
}
isStatelessSession = smd.isStateless();
}
Class pkClass = null;
if(!isSession)
{
EntityMetaData metaData = (EntityMetaData) bmd;
String pkClassName = metaData.getPrimaryKeyClass();
try
{
if(pkClassName != null)
{
pkClass = container.getClassLoader().loadClass(pkClassName);
}
else
{
pkClass
= container.getClassLoader()
.loadClass(metaData.getEjbClass())
.getField(metaData.getPrimKeyField())
.getClass();
}
}
catch(NoSuchFieldException e)
{
log.error(
"Unable to identify Bean's Primary Key class!"
+ " Did you specify a primary key class and/or field? Does that field exist?"
);
throw new RuntimeException("Primary Key Problem");
}
catch(NullPointerException e)
{
log.error(
"Unable to identify Bean's Primary Key class!"
+ " Did you specify a primary key class and/or field? Does that field exist?"
);
throw new RuntimeException("Primary Key Problem");
}
}
ejbMetaData = new EJBMetaDataImpl(
((EJBProxyFactoryContainer) container).getRemoteClass(),
((EJBProxyFactoryContainer) container).getHomeClass(),
pkClass, //null if not entity
isSession, //Session
isStatelessSession, //Stateless
new HomeHandleImpl(jndiBinding)
);
log.debug("Proxy Factory for " + jndiBinding + " initialized");
initInterceptorClasses();
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
public void start() throws Exception
{
if(!isServiceEndpointOnly)
{
setupInvokers();
bindProxy();
}
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
protected void setupInvokers() throws Exception
{
ObjectName oname = new ObjectName(invokerMetaData.getInvokerMBean());
Invoker invoker = (Invoker) Registry.lookup(oname);
if(invoker == null)
{
throw new RuntimeException("invoker is null: " + oname);
}
homeInvoker = beanInvoker = invoker;
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
protected void initInterceptorClasses() throws Exception
{
HashMap interceptors = new HashMap();
Element proxyConfig = invokerMetaData.getProxyFactoryConfig();
Element clientInterceptors = MetaData.getOptionalChild(
proxyConfig,
"client-interceptors", null
);
if(clientInterceptors != null)
{
String value = MetaData.getElementAttribute(clientInterceptors, "exposeContainer");
this.includeIClientIface = Boolean.valueOf(value).booleanValue();
NodeList children = clientInterceptors.getChildNodes();
for(int i = 0; i < children.getLength(); i++)
{
Node currentChild = children.item(i);
if(currentChild.getNodeType() == Node.ELEMENT_NODE)
{
Element interceptor = (Element) children.item(i);
interceptors.put(interceptor.getTagName(), interceptor);
}
}
}
else
{
log.debug("client interceptors element is null");
}
Element homeInterceptorConf = (Element) interceptors.get(HOME_INTERCEPTOR);
loadInterceptorClasses(homeInterceptorClasses, homeInterceptorConf);
if(homeInterceptorClasses.size() == 0)
{
throw new DeploymentException("There are no home interface interceptors configured");
}
Element beanInterceptorConf = (Element) interceptors.get(BEAN_INTERCEPTOR);
loadInterceptorClasses(beanInterceptorClasses, beanInterceptorConf);
if(beanInterceptorClasses.size() == 0)
{
throw new DeploymentException("There are no bean interface interceptors configured");
}
Element listEntityInterceptorConf = (Element) interceptors.get(LIST_ENTITY_INTERCEPTOR);
loadInterceptorClasses(listEntityInterceptorClasses, listEntityInterceptorConf);
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
protected void loadInterceptorClasses(ArrayList classes, Element interceptors)
throws Exception
{
Iterator interceptorElements = MetaData.getChildrenByTagName(interceptors, "interceptor");
ClassLoader loader = container.getClassLoader();
while(interceptorElements != null && interceptorElements.hasNext())
{
Element ielement = (Element) interceptorElements.next();
String className = null;
className = MetaData.getElementContent(ielement);
// load the invoker interceptor that corresponds to the beans call semantic
String byValueAttr = MetaData.getElementAttribute(ielement, "call-by-value");
if(byValueAttr != null)
{
if (container.isCallByValue() == new Boolean(byValueAttr).booleanValue())
{
Class clazz = loader.loadClass(className);
classes.add(clazz);
}
}
else
{
Class clazz = loader.loadClass(className);
classes.add(clazz);
}
}
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
protected void loadInterceptorChain(ArrayList chain, ClientContainer client)
throws Exception
{
Interceptor last = null;
for(int i = 0; i < chain.size(); i++)
{
Class clazz = (Class) chain.get(i);
Interceptor interceptor = (Interceptor) clazz.newInstance();
if(last == null)
{
last = interceptor;
client.setNext(interceptor);
}
else
{
last.setNext(interceptor);
last = interceptor;
}
}
}
// in src/main/java/org/jboss/proxy/ejb/ProxyFactory.java
protected void bindProxy() throws Exception
{
try
{
// Create a stack from the description (in the future) for now we hardcode it
InvocationContext context = new InvocationContext();
context.setObjectName(jmxNameHashInteger);
context.setValue(InvocationKey.JNDI_NAME, jndiBinding);
// The behavior for home proxying should be isolated in an interceptor FIXME
context.setInvoker(homeInvoker);
context.setValue(InvocationKey.EJB_METADATA, ejbMetaData);
context.setInvokerProxyBinding(invokerMetaData.getName());
if(container.getSecurityManager() != null)
{
String secDomain = container.getSecurityManager().getSecurityDomain();
context.setValue(InvocationKey.SECURITY_DOMAIN, secDomain);
}
ClientContainer client = null;
EJBProxyFactoryContainer pfc = (EJBProxyFactoryContainer) container;
Class[] ifaces = {pfc.getHomeClass(), Class.forName("javax.ejb.Handle")};
if( includeIClientIface )
{
ifaces = new Class[] {IClientContainer.class, pfc.getHomeClass(),
Class.forName("javax.ejb.Handle")};
client = new ClientContainerEx(context);
}
else
{
client = new ClientContainer(context);
}
loadInterceptorChain(homeInterceptorClasses, client);
// Create the EJBHome
this.home = (EJBHome) Proxy.newProxyInstance(
// Class loader pointing to the right classes from deployment
pfc.getHomeClass().getClassLoader(),
// The classes we want to implement home and handle
ifaces,
// The home proxy as invocation handler
client);
// Create stateless session object
// Same instance is used for all objects
if(ejbMetaData.isStatelessSession() == true)
{
// Create a stack from the description (in the future) for now we hardcode it
context = new InvocationContext();
context.setObjectName(jmxNameHashInteger);
context.setValue(InvocationKey.JNDI_NAME, jndiBinding);
// The behavior for home proxying should be isolated in an interceptor FIXME
context.setInvoker(beanInvoker);
context.setInvokerProxyBinding(invokerMetaData.getName());
context.setValue(InvocationKey.EJB_HOME, home);
if(container.getSecurityManager() != null)
{
String secDomain = container.getSecurityManager().getSecurityDomain();
context.setValue(InvocationKey.SECURITY_DOMAIN, secDomain);
}
Class[] ssifaces = {pfc.getRemoteClass()};
if( includeIClientIface )
{
ssifaces = new Class[] {IClientContainer.class, pfc.getRemoteClass()};
client = new ClientContainerEx(context);
}
else
{
client = new ClientContainer(context);
}
loadInterceptorChain(beanInterceptorClasses, client);
this.statelessObject =
(EJBObject)Proxy.newProxyInstance(
// Correct CL
pfc.getRemoteClass().getClassLoader(),
// Interfaces
ssifaces,
// SLSB proxy as invocation handler
client
);
}
else
{
// this is faster than newProxyInstance
Class[] intfs = {pfc.getRemoteClass()};
if( this.includeIClientIface )
{
intfs = new Class[]{IClientContainer.class, pfc.getRemoteClass()};
}
Class proxyClass = Proxy.getProxyClass(pfc.getRemoteClass().getClassLoader(), intfs);
final Class[] constructorParams = {InvocationHandler.class};
proxyClassConstructor = proxyClass.getConstructor(constructorParams);
}
// Bind the home in the JNDI naming space
rebindHomeProxy();
}
catch(Exception e)
{
throw new ServerException("Could not bind home", e);
}
}
// in src/main/java/org/jboss/proxy/ejb/SecurityContextInterceptor.java
private SecurityContext createSecurityContext(Invocation invocation) throws Exception
{
//There may be principal set on the invocation
Principal p = invocation.getPrincipal();
Object cred = invocation.getCredential();
//Create a new SecurityContext
String domain = (String) invocation.getInvocationContext().getValue(InvocationKey.SECURITY_DOMAIN);
if(domain == null)
domain = "CLIENT_PROXY";
return SecurityActions.createSecurityContext(p,cred, domain);
}
// in src/main/java/org/jboss/proxy/GenericProxyFactory.java
protected void loadInterceptorChain(ArrayList chain, ClientContainer client)
throws Exception
{
Interceptor last = null;
for (int i = 0; i < chain.size(); i++)
{
Class clazz = (Class)chain.get(i);
Interceptor interceptor = (Interceptor) clazz.newInstance();
if (last == null)
{
last = interceptor;
client.setNext(interceptor);
}
else
{
last.setNext(interceptor);
last = interceptor;
}
}
}
// in src/etc/class.java
public void startService() throws Exception
{ // Use the newline for the opening bracket so we can match top and bottom bracket visually
Class cls = Class.forName(dataSourceClass);
vendorSource = (XADataSource)cls.newInstance();
// JUMP A LINE BETWEEN LOGICALLY DISCTINT **STEPS** AND ADD A LINE OF COMMENT TO IT
cls = vendorSource.getClass();
if(properties != null && properties.length() > 0)
{
try
{
}
catch (IOException ioe)
{
}
for (Iterator i = props.entrySet().iterator(); i.hasNext();)
{
// Get the name and value for the attributes
Map.Entry entry = (Map.Entry) i.next();
String attributeName = (String) entry.getKey();
String attributeValue = (String) entry.getValue();
// Print the debug message
log.debug("Setting attribute '" + attributeName + "' to '" +
attributeValue + "'");
// get the attribute
Method setAttribute =
cls.getMethod("set" + attributeName,
new Class[] { String.class });
// And set the value
setAttribute.invoke(vendorSource,
new Object[] { attributeValue });
}
}
// Test database
vendorSource.getXAConnection().close();
// Bind in JNDI
bind(new InitialContext(), "java:/"+getPoolName(),
new Reference(vendorSource.getClass().getName(),
getClass().getName(), null));
}