You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by da...@apache.org on 2004/11/23 21:37:05 UTC
svn commit: r106345 - in geronimo/trunk/modules/kernel/src/java/org/apache/geronimo: gbean/jmx kernel
Author: dain
Date: Tue Nov 23 12:37:03 2004
New Revision: 106345
Added:
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractGBeanReference.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionProxy.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionReference.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanReference.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleProxy.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleReference.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleAdapter.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleListener.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleMonitor.java
Removed:
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CollectionProxy.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBeanReference.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/Proxy.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/SingleProxy.java
Modified:
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java
geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java
Log:
Fixed lifecycle notification bugs.
Moved notification monitor code from GBeanReference to a LifecycleMonitor kernel service.
The LifecycleMoniter serverice should NOT be used until we are happy with it.
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractGBeanReference.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractGBeanReference.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractGBeanReference.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,260 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.gbean.jmx;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+
+import org.apache.geronimo.kernel.LifecycleAdapter;
+import org.apache.geronimo.kernel.LifecycleListener;
+import org.apache.geronimo.gbean.GReferenceInfo;
+import org.apache.geronimo.gbean.InvalidConfigurationException;
+import org.apache.geronimo.kernel.ClassLoading;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.kernel.LifecycleListener;
+import org.apache.geronimo.kernel.LifecycleAdapter;
+import org.apache.geronimo.kernel.management.State;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractGBeanReference implements GBeanReference {
+ /**
+ * Name of this reference.
+ */
+ private final String name;
+
+ /**
+ * Interface this GBeanMBean uses to refer to the other.
+ */
+ private final Class type;
+
+ /**
+ * The GBeanMBean to which this reference belongs.
+ */
+ private final GBeanMBean gmbean;
+
+ /**
+ * The method that will be called to set the attribute value. If null, the value will be set with
+ * a constructor argument
+ */
+ private final MethodInvoker setInvoker;
+
+ /**
+ * The target objectName patterns to watch for a connection.
+ */
+ private Set patterns = Collections.EMPTY_SET;
+
+ /**
+ * Our listener for lifecycle events
+ */
+ private final LifecycleListener listener;
+
+ /**
+ * Current set of targets
+ */
+ private final Set targets = new HashSet();
+
+ /**
+ * The kernel to which the reference is bound.
+ */
+ private Kernel kernel;
+
+ public AbstractGBeanReference(GBeanMBean gmbean, GReferenceInfo referenceInfo, Class constructorType) throws InvalidConfigurationException {
+ this.gmbean = gmbean;
+ this.name = referenceInfo.getName();
+ try {
+ this.type = ClassLoading.loadClass(referenceInfo.getType(), gmbean.getClassLoader());
+ } catch (ClassNotFoundException e) {
+ throw new InvalidConfigurationException("Could not load reference proxy interface class:" +
+ " name=" + name +
+ " class=" + referenceInfo.getType());
+ }
+ if (Modifier.isFinal(type.getModifiers())) {
+ throw new IllegalArgumentException("Proxy interface cannot be a final class: " + type.getName());
+ }
+
+ if (constructorType != null) {
+ setInvoker = null;
+ } else {
+ Method setterMethod = searchForSetter(gmbean, referenceInfo);
+ setInvoker = new FastMethodInvoker(setterMethod);
+ }
+
+ listener = new LifecycleAdapter() {
+ public void running(ObjectName objectName) {
+ if (!targets.contains(objectName)) {
+ targets.add(objectName);
+ targetAdded(objectName);
+ }
+ }
+
+ public void stoping(ObjectName objectName) {
+ boolean wasTarget = targets.remove(objectName);
+ if (wasTarget) {
+ targetRemoved(objectName);
+ }
+ }
+ };
+ }
+
+ protected final Kernel getKernel() {
+ return kernel;
+ }
+
+ protected final GBeanMBean getGBeanMBean() {
+ return gmbean;
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ public final Class getType() {
+ return type;
+ }
+
+ public final Set getPatterns() {
+ return patterns;
+ }
+
+ public final void setPatterns(Set patterns) {
+ if (kernel != null) {
+ throw new IllegalStateException("Pattern set can not be modified while online");
+ }
+
+ if (patterns == null || patterns.isEmpty() || (patterns.size() == 1 && patterns.iterator().next() == null)) {
+ this.patterns = Collections.EMPTY_SET;
+ } else {
+ patterns = new HashSet(patterns);
+ for (Iterator iterator = this.patterns.iterator(); iterator.hasNext();) {
+ if (iterator.next() == null) {
+ iterator.remove();
+ //there can be at most one null value in a set.
+ break;
+ }
+ }
+ this.patterns = Collections.unmodifiableSet(patterns);
+ }
+ }
+
+ public final synchronized void online(Kernel kernel) {
+ this.kernel = kernel;
+
+ Set gbeans = kernel.listGBeans(patterns);
+ for (Iterator objectNameIterator = gbeans.iterator(); objectNameIterator.hasNext();) {
+ ObjectName target = (ObjectName) objectNameIterator.next();
+ if (!targets.contains(target)) {
+
+ // if the bean is running add it to the runningTargets list
+ if (isRunning(kernel, target)) {
+ targets.add(target);
+ }
+ }
+ }
+
+ kernel.getLifecycleMonitor().addLifecycleListener(listener, patterns);
+ }
+
+ public final synchronized void offline() {
+ // make sure we are stoped
+ stop();
+
+ kernel.getLifecycleMonitor().removeLifecycleListener(listener);
+
+ targets.clear();
+ kernel = null;
+ }
+
+ protected abstract void targetAdded(ObjectName target);
+
+ protected abstract void targetRemoved(ObjectName target);
+
+ protected final Set getTargets() {
+ return targets;
+ }
+
+ public final synchronized void inject() throws Exception {
+ // set the proxy into the instance
+ if (setInvoker != null && patterns.size() > 0) {
+ setInvoker.invoke(gmbean.getTarget(), new Object[]{getProxy()});
+ }
+ }
+
+ /**
+ * Is the component in the Running state
+ *
+ * @param objectName name of the component to check
+ * @return true if the component is running; false otherwise
+ */
+ private boolean isRunning(Kernel kernel, ObjectName objectName) {
+ try {
+ final int state = ((Integer) kernel.getAttribute(objectName, "state")).intValue();
+ return state == State.RUNNING_INDEX;
+ } catch (AttributeNotFoundException e) {
+ // ok -- mbean is not a startable
+ return true;
+ } catch (InstanceNotFoundException e) {
+ // mbean is no longer registerd
+ return false;
+ } catch (Exception e) {
+ // problem getting the attribute, mbean has most likely failed
+ return false;
+ }
+ }
+
+ protected static Method searchForSetter(GBeanMBean gMBean, GReferenceInfo referenceInfo) throws InvalidConfigurationException {
+ if (referenceInfo.getSetterName() == null) {
+ // no explicit name give so we must search for a name
+ String setterName = "set" + referenceInfo.getName();
+ Method[] methods = gMBean.getType().getMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.getParameterTypes().length == 1 &&
+ method.getReturnType() == Void.TYPE &&
+ setterName.equalsIgnoreCase(method.getName())) {
+
+ return method;
+ }
+ }
+ } else {
+ // even though we have an exact name we need to search the methods because
+ // we don't know the parameter type
+ Method[] methods = gMBean.getType().getMethods();
+ String setterName = referenceInfo.getSetterName();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.getParameterTypes().length == 1 &&
+ method.getReturnType() == Void.TYPE &&
+ setterName.equals(method.getName())) {
+
+ return method;
+ }
+ }
+ }
+ throw new InvalidConfigurationException("Target does not have specified method:" +
+ " name=" + referenceInfo.getName() +
+ " targetClass=" + gMBean.getType().getName());
+ }
+}
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/AbstractManagedObject.java Tue Nov 23 12:37:03 2004
@@ -166,10 +166,10 @@
}
public void preDeregister() throws Exception {
+ sendNotification(NotificationType.OBJECT_DELETED);
}
public void postDeregister() {
- sendNotification(NotificationType.OBJECT_DELETED);
synchronized (this) {
server = null;
objectName = null;
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibMethodInterceptor.java Tue Nov 23 12:37:03 2004
@@ -67,13 +67,9 @@
}
public synchronized void connect(MBeanServerConnection server, ObjectName objectName) {
- this.connect(server, objectName, false);
- }
-
- public synchronized void connect(MBeanServerConnection server, ObjectName objectName, boolean stopped) {
assert server != null && objectName != null;
this.objectName = objectName;
- this.stopped = stopped;
+ stopped = false;
gbeanInvokers = createGBeanInvokers(server, objectName);
}
@@ -81,17 +77,6 @@
stopped = true;
objectName = null;
gbeanInvokers = null;
- }
-
- public synchronized void start() {
- if (gbeanInvokers == null) {
- throw new IllegalStateException("Proxy is not connected");
- }
- this.stopped = false;
- }
-
- public synchronized void stop() {
- this.stopped = true;
}
public final Object intercept(final Object object, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CGLibProxyFactory.java Tue Nov 23 12:37:03 2004
@@ -16,8 +16,6 @@
*/
package org.apache.geronimo.gbean.jmx;
-import java.lang.reflect.InvocationTargetException;
-
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
Deleted: /geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CollectionProxy.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/CollectionProxy.java?view=auto&rev=106344
==============================================================================
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionProxy.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionProxy.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionProxy.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,293 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.gbean.jmx;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import javax.management.ObjectName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gbean.ReferenceCollection;
+import org.apache.geronimo.gbean.ReferenceCollectionEvent;
+import org.apache.geronimo.gbean.ReferenceCollectionListener;
+import org.apache.geronimo.kernel.Kernel;
+
+/**
+ * @version $Rev: 46019 $ $Date: 2004-09-14 02:56:06 -0700 (Tue, 14 Sep 2004) $
+ */
+public class GBeanCollectionProxy {
+ private static final Log log = LogFactory.getLog(GBeanCollectionProxy.class);
+
+ /**
+ * Name of the reference
+ */
+ public String name;
+
+ /**
+ * A map from object names to the proxy
+ */
+ private Map proxies = new HashMap();
+
+ /**
+ * A map from object names to the proxy interceptor
+ */
+ private Map interceptors = new HashMap();
+
+ /**
+ * Proxy collection implementation held by the component
+ */
+ private ClientCollection proxy = new ClientCollection();
+
+ /**
+ * Facotry for proxy instances.
+ */
+ private ProxyFactory factory;
+ private Kernel kernel;
+
+ public GBeanCollectionProxy(Kernel kernel, String name, Class type, Set targets) {
+ this.kernel = kernel;
+ this.name = name;
+ factory = ProxyFactory.newProxyFactory(type);
+
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ addTarget((ObjectName) iterator.next());
+ }
+ }
+
+ public synchronized void destroy() {
+ for (Iterator iterator = interceptors.values().iterator(); iterator.hasNext();) {
+ ProxyMethodInterceptor interceptor = (ProxyMethodInterceptor) iterator.next();
+ interceptor.disconnect();
+ }
+ proxy.listeners = null;
+ kernel = null;
+ name = null;
+ proxies = null;
+ interceptors = null;
+ proxy = null;
+ factory = null;
+ }
+
+ public synchronized Object getProxy() {
+ return proxy;
+ }
+
+ public synchronized void addTarget(ObjectName target) {
+ // if this is a new target...
+ if (!proxies.containsKey(target)) {
+ // create the interceptor
+ ProxyMethodInterceptor interceptor = factory.getMethodInterceptor();
+ interceptor.connect(kernel.getMBeanServer(), target);
+ interceptors.put(target, interceptor);
+
+ // create the proxy
+ Object targetProxy = factory.create(interceptor);
+ proxies.put(target, targetProxy);
+ proxy.fireMemberAdddedEvent(targetProxy);
+ }
+ }
+
+ public synchronized void removeTarget(ObjectName target) {
+ Object targetProxy = proxies.remove(target);
+ if (targetProxy != null) {
+ proxy.fireMemberRemovedEvent(targetProxy);
+ ProxyMethodInterceptor interceptor = (ProxyMethodInterceptor) interceptors.remove(target);
+ if (interceptor != null) {
+ interceptor.disconnect();
+ }
+ }
+ }
+
+ private class ClientCollection implements ReferenceCollection {
+ private Set listeners = new HashSet();
+
+ public boolean isStopped() {
+ synchronized (GBeanCollectionProxy.this) {
+ return proxy == null;
+ }
+ }
+
+ public void addReferenceCollectionListener(ReferenceCollectionListener listener) {
+ synchronized (GBeanCollectionProxy.this) {
+ listeners.add(listener);
+ }
+ }
+
+ public void removeReferenceCollectionListener(ReferenceCollectionListener listener) {
+ synchronized (GBeanCollectionProxy.this) {
+ listeners.remove(listener);
+ }
+ }
+
+ private void fireMemberAdddedEvent(Object member) {
+ ArrayList listenerCopy;
+ synchronized (GBeanCollectionProxy.this) {
+ listenerCopy = new ArrayList(listeners);
+ }
+ for (Iterator iterator = listenerCopy.iterator(); iterator.hasNext();) {
+ ReferenceCollectionListener listener = (ReferenceCollectionListener) iterator.next();
+ try {
+ listener.memberAdded(new ReferenceCollectionEvent(name, member));
+ } catch (Throwable t) {
+ log.error("Listener threw exception", t);
+ }
+ }
+ }
+
+ private void fireMemberRemovedEvent(Object member) {
+ ArrayList listenerCopy;
+ synchronized (GBeanCollectionProxy.this) {
+ listenerCopy = new ArrayList(listeners);
+ }
+ for (Iterator iterator = listenerCopy.iterator(); iterator.hasNext();) {
+ ReferenceCollectionListener listener = (ReferenceCollectionListener) iterator.next();
+ try {
+ listener.memberRemoved(new ReferenceCollectionEvent(name, member));
+ } catch (Throwable t) {
+ log.error("Listener threw exception", t);
+ }
+ }
+ }
+
+ public int size() {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ return 0;
+ }
+ return proxies.size();
+ }
+ }
+
+ public boolean isEmpty() {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ return true;
+ }
+ return proxies.isEmpty();
+ }
+ }
+
+ public boolean contains(Object o) {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ return false;
+ }
+ return proxies.containsValue(o);
+ }
+ }
+
+ public Iterator iterator() {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ return new Iterator() {
+ public boolean hasNext() {
+ return false;
+ }
+
+ public Object next() {
+ throw new NoSuchElementException();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+
+ return new Iterator() {
+ // copy the proxies, so the client can iterate without concurrent modification
+ // this is necssary since the client has nothing to synchronize on
+ private final Iterator iterator = new ArrayList(proxies.values()).iterator();
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ public Object next() {
+ return iterator.next();
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ }
+
+ public Object[] toArray() {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ return new Object[0];
+ }
+ return proxies.values().toArray();
+ }
+ }
+
+ public Object[] toArray(Object a[]) {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ if (a.length > 0) {
+ a[0] = null;
+ }
+ return a;
+ }
+ return proxies.values().toArray(a);
+ }
+ }
+
+ public boolean containsAll(Collection c) {
+ synchronized (GBeanCollectionProxy.this) {
+ if (proxy == null) {
+ return c.isEmpty();
+ }
+ return proxies.values().containsAll(c);
+ }
+ }
+
+ public boolean add(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean remove(Object o) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean addAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean removeAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean retainAll(Collection c) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void clear() {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionReference.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionReference.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanCollectionReference.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,79 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.gbean.jmx;
+
+import javax.management.ObjectName;
+
+import org.apache.geronimo.gbean.GReferenceInfo;
+import org.apache.geronimo.gbean.InvalidConfigurationException;
+
+/**
+ * @version $Rev: 71492 $ $Date: 2004-11-14 21:31:50 -0800 (Sun, 14 Nov 2004) $
+ */
+public class GBeanCollectionReference extends AbstractGBeanReference {
+ /**
+ * Proxy to the to this connection.
+ */
+ private GBeanCollectionProxy proxy;
+
+ public GBeanCollectionReference(GBeanMBean gmbean, GReferenceInfo referenceInfo, Class constructorType) throws InvalidConfigurationException {
+ super(gmbean, referenceInfo, constructorType);
+ }
+
+ public synchronized void start() throws Exception {
+ // if there are no patterns then there is nothing to start
+ if (getPatterns().isEmpty()) {
+ return;
+ }
+
+ // if we already have a proxy then we have already been started
+ if (proxy != null) {
+ return;
+ }
+
+ // add a dependency on our target and create the proxy
+ proxy = new GBeanCollectionProxy(getKernel(), getName(), getType(), getTargets());
+ }
+
+ public synchronized void stop() {
+ if (proxy != null) {
+ proxy.destroy();
+ proxy = null;
+ }
+ }
+
+ public Object getProxy() {
+ if (proxy == null) {
+ return null;
+ } else {
+ return proxy.getProxy();
+ }
+ }
+
+ public synchronized void targetAdded(ObjectName target) {
+ if (proxy != null) {
+ proxy.addTarget(target);
+ }
+ }
+
+ public synchronized void targetRemoved(ObjectName target) {
+ if (proxy != null) {
+ proxy.removeTarget(target);
+ }
+ }
+}
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBean.java Tue Nov 23 12:37:03 2004
@@ -19,6 +19,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -45,6 +46,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.GAttributeInfo;
+import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.gbean.GBeanLifecycleController;
@@ -53,7 +55,7 @@
import org.apache.geronimo.gbean.GOperationSignature;
import org.apache.geronimo.gbean.GReferenceInfo;
import org.apache.geronimo.gbean.InvalidConfigurationException;
-import org.apache.geronimo.gbean.GBeanData;
+import org.apache.geronimo.gbean.WaitingException;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.kernel.management.NotificationType;
@@ -106,7 +108,7 @@
/**
* References lookup table
*/
- private final GBeanMBeanReference[] references;
+ private final GBeanReference[] references;
/**
* References supported by this GBeanMBean by (String) name.
@@ -173,6 +175,8 @@
*/
private final RawInvoker rawInvoker;
+ private Kernel kernel;
+
/**
* Constructa a GBeanMBean using the supplied GBeanData and class loader
*
@@ -238,9 +242,14 @@
Set referencesSet = new HashSet();
for (Iterator iterator = gbeanInfo.getReferences().iterator(); iterator.hasNext();) {
GReferenceInfo referenceInfo = (GReferenceInfo) iterator.next();
- referencesSet.add(new GBeanMBeanReference(this, referenceInfo, (Class) constructorTypes.get(referenceInfo.getName())));
+ Class constructorType = (Class) constructorTypes.get(referenceInfo.getName());
+ if (isCollectionValuedReference(this, referenceInfo, constructorType)) {
+ referencesSet.add(new GBeanCollectionReference(this, referenceInfo, constructorType));
+ } else {
+ referencesSet.add(new GBeanSingleReference(this, referenceInfo, constructorType));
+ }
}
- references = (GBeanMBeanReference[]) referencesSet.toArray(new GBeanMBeanReference[gbeanInfo.getReferences().size()]);
+ references = (GBeanReference[]) referencesSet.toArray(new GBeanReference[gbeanInfo.getReferences().size()]);
for (int i = 0; i < references.length; i++) {
referenceIndex.put(references[i].getName(), new Integer(i));
}
@@ -297,6 +306,15 @@
gbeanLifecycleController = new GBeanMBeanLifecycleController(this);
}
+ private static boolean isCollectionValuedReference(GBeanMBean gbeanMBean, GReferenceInfo referenceInfo, Class constructorType) {
+ if (constructorType != null) {
+ return Collection.class == constructorType;
+ } else {
+ Method setterMethod = AbstractGBeanReference.searchForSetter(gbeanMBean, referenceInfo);
+ return Collection.class == setterMethod.getParameterTypes()[0];
+ }
+ }
+
/**
* Search for a single valid constructor in the class. A valid constructor is determined by the
* attributes and references declared in the GBeanInfo. For each, constructor gbean attribute
@@ -523,17 +541,12 @@
setAttribute("classLoader", classLoader);
try {
String kernelName = (String) server.getAttribute(Kernel.KERNEL, "KernelName");
- Kernel kernel = Kernel.getKernel(kernelName);
+ kernel = Kernel.getKernel(kernelName);
setAttribute("kernel", kernel);
} catch (Exception e) {
setAttribute("kernel", null);
}
- // bring any reference not used in the constructor online
- for (int i = 0; i < references.length; i++) {
- references[i].online();
- }
-
return returnValue;
}
@@ -542,39 +555,50 @@
if (registrationDone.booleanValue()) {
// we're now offically on line
- offline = false;
- } else {
- // we need to bring the reference back off line
for (int i = 0; i < references.length; i++) {
- references[i].offline();
+ references[i].online(kernel);
}
+ offline = false;
+ } else {
+ kernel = null;
target = null;
}
}
public void postDeregister() {
- // take all of the reference offline
+ // just to be sure, stop all the references again
for (int i = 0; i < references.length; i++) {
references[i].offline();
}
offline = true;
+ kernel = null;
target = null;
super.postDeregister();
}
protected void doStart() throws Exception {
- // start all of the proxies
+ // start each of the references... if they need to wait remember the
+ // waiting exception so we can throw it later. this way we the dependecies
+ // are held until we can start
+ WaitingException waitingException = null;
for (int i = 0; i < references.length; i++) {
- references[i].start();
+ try {
+ references[i].start();
+ } catch (WaitingException e) {
+ waitingException = e;
+ }
+ }
+ if (waitingException != null) {
+ throw waitingException;
}
GConstructorInfo constructorInfo = gbeanInfo.getConstructor();
Class[] parameterTypes = constructor.getParameterTypes();
- // create parameter array
+ // create constructor parameter array
Object[] parameters = new Object[parameterTypes.length];
Iterator names = constructorInfo.getAttributeNames().iterator();
for (int i = 0; i < parameters.length; i++) {
@@ -614,7 +638,7 @@
attributes[i].inject();
}
- // inject the proxy into the new instance
+ // inject the proxies into the new instance
for (int i = 0; i < references.length; i++) {
references[i].inject();
}
@@ -641,6 +665,7 @@
for (int i = 0; i < attributes.length; i++) {
GBeanMBeanAttribute attribute = attributes[i];
if (attribute.isPersistent() && attribute.isReadable()) {
+ // copy the current attribute value to the persistent value
Object value = attribute.getValue();
attribute.setPersistentValue(value);
}
@@ -748,7 +773,7 @@
// add the references
for (int i = 0; i < references.length; i++) {
- GBeanMBeanReference reference = references[i];
+ GBeanReference reference = references[i];
String name = reference.getName();
Set patterns = reference.getPatterns();
gbeanData.setReferencePatterns(name, patterns);
@@ -943,12 +968,12 @@
getReferenceByName(name).setPatterns(patterns);
}
- private GBeanMBeanReference getReferenceByName(String name) {
+ private GBeanReference getReferenceByName(String name) {
Integer index = (Integer) referenceIndex.get(name);
if (index == null) {
throw new IllegalArgumentException("Unknown reference " + name);
}
- GBeanMBeanReference reference = references[index.intValue()];
+ GBeanReference reference = references[index.intValue()];
return reference;
}
Deleted: /geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBeanReference.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanMBeanReference.java?view=auto&rev=106344
==============================================================================
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanReference.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanReference.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanReference.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,46 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.gbean.jmx;
+
+import java.util.Set;
+
+import org.apache.geronimo.kernel.Kernel;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface GBeanReference {
+ String getName();
+
+ Class getType();
+
+ Set getPatterns();
+
+ void setPatterns(Set patterns);
+
+ void online(Kernel kernel);
+
+ void offline();
+
+ void start() throws Exception;
+
+ void stop();
+
+ Object getProxy();
+
+ void inject() throws Exception;
+}
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleProxy.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleProxy.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleProxy.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,70 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.gbean.jmx;
+
+import javax.management.ObjectName;
+
+import org.apache.geronimo.kernel.Kernel;
+
+/**
+ * @version $Rev: 46019 $ $Date: 2004-09-14 02:56:06 -0700 (Tue, 14 Sep 2004) $
+ */
+public class GBeanSingleProxy {
+ /**
+ * The GBean we are proxying.
+ */
+ private ObjectName target;
+
+ /**
+ * Proxy implementation held by the component
+ */
+ private Object proxy;
+
+ /**
+ * The interceptor for the proxy instance
+ */
+ private ProxyMethodInterceptor methodInterceptor;
+
+ public GBeanSingleProxy(Kernel kernel, Class type, ObjectName target) throws Exception {
+ assert kernel != null: "kernel is null";
+ assert type != null: "type is null";
+ assert target != null: "target is null";
+
+ this.target = target;
+ ProxyFactory factory = ProxyFactory.newProxyFactory(type);
+ methodInterceptor = factory.getMethodInterceptor();
+ proxy = factory.create(methodInterceptor);
+
+ methodInterceptor.connect(kernel.getMBeanServer(), target);
+ }
+
+ public synchronized void destroy() {
+ methodInterceptor.disconnect();
+
+ proxy = null;
+ methodInterceptor = null;
+ }
+
+ public synchronized Object getProxy() {
+ return proxy;
+ }
+
+ public ObjectName getTarget() {
+ return target;
+ }
+}
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleReference.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleReference.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/GBeanSingleReference.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,150 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.gbean.jmx;
+
+import java.util.Set;
+import javax.management.ObjectName;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gbean.GReferenceInfo;
+import org.apache.geronimo.gbean.InvalidConfigurationException;
+import org.apache.geronimo.gbean.WaitingException;
+import org.apache.geronimo.kernel.Kernel;
+import org.apache.geronimo.kernel.management.State;
+
+/**
+ * @version $Rev: 71492 $ $Date: 2004-11-14 21:31:50 -0800 (Sun, 14 Nov 2004) $
+ */
+public class GBeanSingleReference extends AbstractGBeanReference {
+ private static final Log log = LogFactory.getLog(GBeanSingleReference.class);
+
+ /**
+ * Is the GBeanMBean waitng for me to start?
+ */
+ private boolean waitingForMe = false;
+
+ /**
+ * Proxy to the to this connection.
+ */
+ private GBeanSingleProxy proxy;
+
+ public GBeanSingleReference(GBeanMBean gmbean, GReferenceInfo referenceInfo, Class constructorType) throws InvalidConfigurationException {
+ super(gmbean, referenceInfo, constructorType);
+ }
+
+ public synchronized void start() throws Exception {
+ // if there are no patterns then there is nothing to start
+ if (getPatterns().isEmpty()) {
+ return;
+ }
+
+ // if we already have a proxy then we have already been started
+ if (proxy != null) {
+ return;
+ }
+
+ //
+ // We must have exactally one running target
+ //
+ Set targets = getTargets();
+ if (targets.size() == 0) {
+ waitingForMe = true;
+ throw new WaitingException("No targets are running for " + getName() + " reference");
+ } else if (targets.size() > 1) {
+ waitingForMe = true;
+ throw new WaitingException("More then one targets are running for " + getName() + " reference");
+ }
+ waitingForMe = false;
+
+ // stop all gbeans that would match our patterns from starting
+ Kernel kernel = getKernel();
+ ObjectName objectName = getGBeanMBean().getObjectNameObject();
+ kernel.getDependencyManager().addStartHolds(objectName, getPatterns());
+
+ // add a dependency on our target and create the proxy
+ ObjectName target = (ObjectName) targets.iterator().next();
+ kernel.getDependencyManager().addDependency(objectName, target);
+ proxy = new GBeanSingleProxy(kernel, getType(), target);
+ }
+
+ public synchronized void stop() {
+ waitingForMe = false;
+ Kernel kernel = getKernel();
+ ObjectName objectName = getGBeanMBean().getObjectNameObject();
+ Set patterns = getPatterns();
+ if (!patterns.isEmpty()) {
+ kernel.getDependencyManager().removeStartHolds(objectName, patterns);
+ }
+
+ if (proxy != null) {
+ kernel.getDependencyManager().removeDependency(objectName, proxy.getTarget());
+ proxy.destroy();
+ proxy = null;
+ }
+ }
+
+ public Object getProxy() {
+ if (proxy == null) {
+ return null;
+ } else {
+ return proxy.getProxy();
+ }
+ }
+
+ public synchronized void targetAdded(ObjectName target) {
+ // if we are running, and we now have two valid targets, which is an illegal state so we need to fail
+ GBeanMBean gbeanMBean = getGBeanMBean();
+ if (gbeanMBean.getStateInstance() == State.RUNNING) {
+ gbeanMBean.fail();
+ } else if (waitingForMe) {
+ Set targets = getTargets();
+ if (targets.size() == 1) {
+ // the gbean was waiting for me and not there is now just one target
+ attemptFullStart();
+ }
+ }
+ }
+
+ public synchronized void targetRemoved(ObjectName target) {
+ GBeanMBean gbeanMBean = getGBeanMBean();
+ if (gbeanMBean.getStateInstance() == State.RUNNING) {
+ // we no longer have a valid target, which is an illegal state so we need to fail
+ gbeanMBean.fail();
+ } else if (waitingForMe) {
+ Set targets = getTargets();
+ if (targets.size() == 1) {
+ // the gbean was waiting for me and not there is now just one target
+ attemptFullStart();
+ }
+ }
+ }
+
+ private synchronized void attemptFullStart() {
+ try {
+ // there could be an issue with really badly written components holding up a stop when the
+ // component never reached the starting phase... then a target registers and we automatically
+ // attempt to restart
+ waitingForMe = false;
+ getGBeanMBean().attemptFullStart();
+ } catch (Exception e) {
+ log.warn("Exception occured while attempting to fully start: objectName=" + getGBeanMBean().getObjectName(), e);
+ }
+ }
+
+}
Deleted: /geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/Proxy.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/Proxy.java?view=auto&rev=106344
==============================================================================
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/ProxyMethodInterceptor.java Tue Nov 23 12:37:03 2004
@@ -27,13 +27,7 @@
void connect(MBeanServerConnection server, ObjectName objectName);
- void connect(MBeanServerConnection server, ObjectName objectName, boolean stopped);
-
void disconnect();
-
- void start();
-
- void stop();
static final class HashCodeInvoke implements GBeanInvoker {
public Object invoke(ObjectName objectName, Object[] arguments) throws Throwable {
Deleted: /geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/SingleProxy.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/SingleProxy.java?view=auto&rev=106344
==============================================================================
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/gbean/jmx/VMMethodInterceptor.java Tue Nov 23 12:37:03 2004
@@ -45,13 +45,9 @@
}
public void connect(MBeanServerConnection server, ObjectName objectName) {
- connect(server, objectName, false);
- }
-
- public void connect(MBeanServerConnection server, ObjectName objectName, boolean stopped) {
assert server != null && objectName != null;
this.objectName = objectName;
- this.stopped = stopped;
+ stopped = false;
gbeanInvokers = createGBeanInvokers(server, objectName);
}
@@ -59,17 +55,6 @@
stopped = true;
objectName = null;
gbeanInvokers = null;
- }
-
- public void start() {
- if (gbeanInvokers == null) {
- throw new DeadProxyException("Proxy is no longer valid");
- }
- this.stopped = false;
- }
-
- public void stop() {
- this.stopped = true;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/DependencyManager.java Tue Nov 23 12:37:03 2004
@@ -193,7 +193,7 @@
if (parents == null) {
return Collections.EMPTY_SET;
}
- return parents;
+ return new HashSet(parents);
}
/**
@@ -208,7 +208,7 @@
if (children == null) {
return Collections.EMPTY_SET;
}
- return children;
+ return new HashSet(children);
}
/**
Modified: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java?view=diff&rev=106345&p1=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java&r1=106344&p2=geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java&r2=106345
==============================================================================
--- geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java (original)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/Kernel.java Tue Nov 23 12:37:03 2004
@@ -28,6 +28,8 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Iterator;
+import java.util.HashSet;
import javax.management.Attribute;
import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
@@ -44,12 +46,12 @@
import org.apache.geronimo.gbean.GBeanData;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.jmx.GBeanMBean;
+import org.apache.geronimo.kernel.config.Configuration;
import org.apache.geronimo.kernel.config.ConfigurationManager;
import org.apache.geronimo.kernel.config.ConfigurationManagerImpl;
import org.apache.geronimo.kernel.config.InvalidConfigException;
import org.apache.geronimo.kernel.config.NoSuchConfigException;
import org.apache.geronimo.kernel.config.NoSuchStoreException;
-import org.apache.geronimo.kernel.config.Configuration;
import org.apache.geronimo.kernel.jmx.JMXUtil;
@@ -158,6 +160,12 @@
private GBeanMBean configurationManagerGBean;
/**
+ * Monitors the lifecycle of all gbeans.
+ * @deprecated don't use this yet... it may go away
+ */
+ private LifecycleMonitor lifecycleMonitor;
+
+ /**
* No-arg constructor allowing this class to be used as a GBean reference.
*/
public Kernel() {
@@ -249,6 +257,14 @@
return configurationManager;
}
+ /**
+ * Gets the lifecycle monitor.
+ * @deprecated don't use this yet... it may change or go away
+ */
+ public LifecycleMonitor getLifecycleMonitor() {
+ return lifecycleMonitor;
+ }
+
public Object getAttribute(ObjectName objectName, String attributeName) throws Exception {
try {
return mbServer.getAttribute(objectName, attributeName);
@@ -404,6 +420,15 @@
return mbServer.queryNames(query, null);
}
+ public Set listGBeans(Set patterns) {
+ Set gbeans = new HashSet();
+ for (Iterator iterator = patterns.iterator(); iterator.hasNext();) {
+ ObjectName pattern = (ObjectName) iterator.next();
+ gbeans.addAll(listGBeans(pattern));
+ }
+ return gbeans;
+ }
+
public List listConfigurationStores() {
return getConfigurationManager().listStores();
}
@@ -479,12 +504,13 @@
mbServer.registerMBean(this, KERNEL);
dependencyManager = new DependencyManager(mbServer);
+ lifecycleMonitor = new LifecycleMonitor(mbServer);
+
configurationManagerGBean = new GBeanMBean(ConfigurationManagerImpl.GBEAN_INFO);
configurationManagerGBean.setReferencePatterns("Stores", Collections.singleton(CONFIGURATION_STORE_PATTERN));
mbServer.registerMBean(configurationManagerGBean, CONFIGURATION_MANAGER_NAME);
configurationManagerGBean.start();
configurationManager = (ConfigurationManager) configurationManagerGBean.getTarget();
-
running = true;
log.info("Booted");
}
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleAdapter.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleAdapter.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleAdapter.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.kernel;
+
+import javax.management.ObjectName;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class LifecycleAdapter implements LifecycleListener {
+ public void created(ObjectName objectName) {
+ }
+
+ public void starting(ObjectName objectName) {
+ }
+
+ public void running(ObjectName objectName) {
+ }
+
+ public void stopping(ObjectName objectName) {
+ }
+
+ public void stopped(ObjectName objectName) {
+ }
+
+ public void deleted(ObjectName objectName) {
+ }
+}
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleListener.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleListener.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleListener.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,32 @@
+/**
+ *
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geronimo.kernel;
+
+import java.util.EventListener;
+import javax.management.ObjectName;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface LifecycleListener extends EventListener {
+ public void created(ObjectName objectName);
+ public void starting(ObjectName objectName);
+ public void running(ObjectName objectName);
+ public void stopping(ObjectName objectName);
+ public void stopped(ObjectName objectName);
+ public void deleted(ObjectName objectName);
+}
Added: geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleMonitor.java
Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleMonitor.java?view=auto&rev=106345
==============================================================================
--- (empty file)
+++ geronimo/trunk/modules/kernel/src/java/org/apache/geronimo/kernel/LifecycleMonitor.java Tue Nov 23 12:37:03 2004
@@ -0,0 +1,276 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.geronimo.kernel;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map;
+import java.util.Collections;
+import java.util.HashMap;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerNotification;
+import javax.management.Notification;
+import javax.management.NotificationFilterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.NotificationBroadcaster;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.kernel.jmx.JMXUtil;
+import org.apache.geronimo.kernel.management.NotificationType;
+
+/**
+ * @version $Rev: 71492 $ $Date: 2004-11-14 21:31:50 -0800 (Sun, 14 Nov 2004) $
+ */
+public class LifecycleMonitor implements NotificationListener {
+ private static final Log log = LogFactory.getLog(LifecycleMonitor.class);
+
+ private final MBeanServer server;
+
+ // todo we should only hold weak references to the listeners
+ private final Map boundListeners = new HashMap();
+ private final Map listenerPatterns = new HashMap();
+
+ /**
+ * @deprecated don't use this yet... it may change or go away
+ */
+ public LifecycleMonitor(MBeanServer server) {
+ this.server = server;
+
+ // listen for all mbean registration events
+ try {
+ NotificationFilterSupport mbeanServerFilter = new NotificationFilterSupport();
+ mbeanServerFilter.enableType(MBeanServerNotification.REGISTRATION_NOTIFICATION);
+ mbeanServerFilter.enableType(MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
+ server.addNotificationListener(JMXUtil.DELEGATE_NAME, this, mbeanServerFilter, null);
+ } catch (Exception e) {
+ // this will never happen... all of the above is well formed
+ throw new AssertionError(e);
+ }
+
+ // register for state change notifications with all mbeans that match the target patterns
+ Set names = server.queryNames(null, null);
+ for (Iterator objectNameIterator = names.iterator(); objectNameIterator.hasNext();) {
+ addSource((ObjectName) objectNameIterator.next());
+ }
+
+ for (Iterator iterator = boundListeners.keySet().iterator(); iterator.hasNext();) {
+ ObjectName source = (ObjectName) iterator.next();
+ try {
+ if (server.isInstanceOf(source, NotificationBroadcaster.class.getName())) {
+ server.addNotificationListener(source, this, NotificationType.STATE_CHANGE_FILTER, null);
+ }
+ } catch (InstanceNotFoundException e) {
+ // the instance died before we could get going... not a big deal
+ break;
+ } catch (Throwable e) {
+ log.warn("Could not add state change listener to: " + source + " on behalf of objectName", e);
+ }
+ }
+ }
+
+ public synchronized void destroy() {
+ try {
+ server.removeNotificationListener(JMXUtil.DELEGATE_NAME, this);
+ } catch (Exception ignore) {
+ // don't care... we tried
+ }
+
+ // unregister for all notifications
+ for (Iterator iterator = boundListeners.keySet().iterator(); iterator.hasNext();) {
+ ObjectName target = (ObjectName) iterator.next();
+ try {
+ server.removeNotificationListener(target, this, NotificationType.STATE_CHANGE_FILTER, null);
+ } catch (Exception ignore) {
+ // don't care... we tried
+ }
+ }
+
+ boundListeners.clear();
+ listenerPatterns.clear();
+ }
+
+ private synchronized void addSource(ObjectName source) {
+ if (boundListeners.containsKey(source)) {
+ // alreayd registered
+ return;
+ }
+
+ // find all listeners interested in events from this source
+ HashSet listeners = new HashSet();
+ for (Iterator listenerIterator = listenerPatterns.entrySet().iterator(); listenerIterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) listenerIterator.next();
+ Set patterns = (Set) entry.getValue();
+ for (Iterator patternIterator = patterns.iterator(); patternIterator.hasNext();) {
+ ObjectName pattern = (ObjectName) patternIterator.next();
+ if (pattern.apply(source)) {
+ LifecycleListener listener = (LifecycleListener) entry.getKey();
+ listeners.add(listener);
+ }
+ }
+ }
+
+ boundListeners.put(source, listeners);
+ }
+
+ private synchronized void removeSource(ObjectName source) {
+ boundListeners.remove(source);
+ }
+
+ public synchronized void addLifecycleListener(LifecycleListener listener, Set patterns) {
+ for (Iterator patternIterator = patterns.iterator(); patternIterator.hasNext();) {
+ ObjectName pattern = (ObjectName) patternIterator.next();
+ for (Iterator iterator = boundListeners.entrySet().iterator(); iterator.hasNext();) {
+ Map.Entry entry = (Map.Entry) iterator.next();
+ ObjectName source = (ObjectName) entry.getKey();
+ if (pattern.apply(source)) {
+ Set listeners = (Set) entry.getValue();
+ listeners.add(listener);
+ }
+ }
+ }
+ listenerPatterns.put(listener, patterns);
+ }
+
+ public synchronized void removeLifecycleListener(LifecycleListener listener) {
+ for (Iterator iterator = boundListeners.values().iterator(); iterator.hasNext();) {
+ Set set = (Set) iterator.next();
+ set.remove(listener);
+ }
+ listenerPatterns.remove(listener);
+ }
+
+ private synchronized Set getTargets(ObjectName source) {
+ Set targets = (Set) boundListeners.get(source);
+ if (targets == null) {
+ // no one is interested in this event
+ return Collections.EMPTY_SET;
+ } else {
+ return new HashSet(targets);
+ }
+ }
+
+ private void fireCreatedEvent(ObjectName objectName) {
+ Set targets = getTargets(objectName);
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ LifecycleListener listener = (LifecycleListener) iterator.next();
+ try {
+ listener.created(objectName);
+ } catch (Throwable e) {
+ log.warn("Exception occured while notifying listener", e);
+ }
+ }
+ }
+
+ private void fireStartingEvent(ObjectName source) {
+ Set targets = getTargets(source);
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ LifecycleListener listener = (LifecycleListener) iterator.next();
+ try {
+ listener.starting(source);
+ } catch (Throwable e) {
+ log.warn("Exception occured while notifying listener", e);
+ }
+ }
+ }
+
+ private void fireRunningEvent(ObjectName source) {
+ Set targets = getTargets(source);
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ LifecycleListener listener = (LifecycleListener) iterator.next();
+ try {
+ listener.running(source);
+ } catch (Throwable e) {
+ log.warn("Exception occured while notifying listener", e);
+ }
+ }
+ }
+
+ private void fireStoppingEvent(ObjectName source) {
+ Set targets = getTargets(source);
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ LifecycleListener listener = (LifecycleListener) iterator.next();
+ try {
+ listener.stopping(source);
+ } catch (Throwable e) {
+ log.warn("Exception occured while notifying listener", e);
+ }
+ }
+ }
+
+ private void fireStoppedEvent(ObjectName source) {
+ Set targets = getTargets(source);
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ LifecycleListener listener = (LifecycleListener) iterator.next();
+ try {
+ listener.stopped(source);
+ } catch (Throwable e) {
+ log.warn("Exception occured while notifying listener", e);
+ }
+ }
+ }
+
+ private void fireDeleteEvent(ObjectName source) {
+ Set targets = getTargets(source);
+ for (Iterator iterator = targets.iterator(); iterator.hasNext();) {
+ LifecycleListener listener = (LifecycleListener) iterator.next();
+ try {
+ listener.deleted(source);
+ } catch (Throwable e) {
+ log.warn("Exception occured while notifying listener", e);
+ }
+ }
+ }
+
+ public void handleNotification(Notification notification, Object o) {
+ String type = notification.getType();
+
+ if (MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(type)) {
+ ObjectName source = ((MBeanServerNotification) notification).getMBeanName();
+ addSource(source);
+
+ // register for state change notifications
+ try {
+ server.addNotificationListener(source, this, NotificationType.STATE_CHANGE_FILTER, null);
+ } catch (InstanceNotFoundException e) {
+ // the instance died before we could get going... not a big deal
+ return;
+ }
+ } else if (MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(type)) {
+ removeSource(((MBeanServerNotification) notification).getMBeanName());
+ } else {
+ final ObjectName source = (ObjectName) notification.getSource();
+ if (NotificationType.OBJECT_CREATED.equals(type)) {
+ fireCreatedEvent(source);
+ } else if (NotificationType.STATE_STARTING.equals(type)) {
+ fireStartingEvent(source);
+ } else if (NotificationType.STATE_RUNNING.equals(type)) {
+ fireRunningEvent(source);
+ } else if (NotificationType.STATE_STOPPING.equals(type)) {
+ fireStoppingEvent(source);
+ } else if (NotificationType.STATE_STOPPED.equals(type)) {
+ fireStoppedEvent(source);
+ } else if (NotificationType.OBJECT_DELETED.equals(type)) {
+ fireDeleteEvent(source);
+ }
+ }
+ }
+}