(callable);
- }
-
- /**
- * Gives the total amount of uncompleted tasks
- */
- int getTotalUncompletedTasks()
- {
- return totalUncompletedTasks.get();
- }
-
- /**
- * Increments and get the total amount of uncompleted tasks
- */
- int incrementAndGetTotalUncompletedTasks()
- {
- return totalUncompletedTasks.incrementAndGet();
- }
-
- /**
- * Indicates whether or not there are some remaining lockable resources
- */
- boolean isEmpty()
- {
- return locks.isEmpty();
- }
-
- /**
- * Registers a lockable resource for the current thread
- */
- private void register(Lockable l)
- {
- locks.put(Thread.currentThread(), l);
- }
-
- /**
- * Unregisters a lockable resource for the current thread
- */
- private void unregister(Lockable l)
- {
- locks.remove(Thread.currentThread(), l);
- }
-
- /**
- * Checks if there is a deadlock, if so an {@link InterruptedException}
- * will be thrown.
- *
- * When two threads enter lockInterruptibly() concurrently, each calls
- * register() and then checkDeadLock() almost simultaneously. There is a
- * window where thread A has already registered but thread B has not yet
- * registered when A runs its check – so A sees an empty entry for B's
- * thread and returns "no deadlock", then both threads block forever.
- *
- * To close this window we retry the walk a few times with a brief yield
- * between attempts. If the deadlock graph materialises within the retry
- * budget we detect and break it; if it never materialises the lock owner
- * really does not hold anything and we let the underlying primitive block
- * normally.
- */
- private void checkDeadLock(Lockable l) throws InterruptedException
- {
- if (!l.isLocked())
- {
- LOG.trace("The lock is not locked so we cannot have a deadlock");
- return;
- }
- final Thread owner = l.getOwner();
- if (owner == null || owner == Thread.currentThread())
- {
- LOG.trace("The lock is not locked or the lock owner is the current "
- + "thread so we cannot have a deadlock");
- return;
- }
- // Retry loop: give concurrent threads a chance to complete their own
- // register() call before we conclude there is no deadlock.
- final int MAX_RETRIES = 10;
- for (int attempt = 0; attempt < MAX_RETRIES; attempt++)
- {
- boolean conclusive = checkDeadLockOnce(l, owner);
- if (conclusive)
- return; // confirmed no deadlock
- // Inconclusive: other thread hasn't registered yet. Yield and retry.
- Thread.yield();
- }
- LOG.trace("No deadlock detected after retries – treating as no deadlock");
- }
-
- /**
- * Single deadlock-graph walk. Returns {@code true} when the walk concludes
- * "no deadlock" with certainty (e.g. the lock became free, or owner chain
- * does not loop back); returns {@code false} when the result is inconclusive
- * because a concurrent thread has not yet completed its register() call
- * (i.e. {@code locks.get(currentOwner)} returned null while the owner is
- * actively running); throws {@link InterruptedException} when a deadlock is
- * confirmed.
- */
- private boolean checkDeadLockOnce(Lockable l, Thread owner) throws InterruptedException
- {
- Thread currentOwner = owner;
- while (true)
- {
- Lockable lock = locks.get(currentOwner);
- if (lock == null)
- {
- // The owner thread is not waiting on anything right now.
- // This could mean it truly holds no other lock (no deadlock),
- // OR it has not finished its register() call yet (inconclusive).
- // We return false (inconclusive) so the caller retries.
- LOG.trace("Owner has no registered lockable resource yet – result inconclusive, will retry");
- return false;
- }
- // We first check the locks
- Thread lockToAcquireOwner = lock.getOwner();
- if (lockToAcquireOwner == null)
- {
- LOG.trace("The lockable resource has no owner anymore so we cannot have a deadlock");
- return true;
- }
- else if (lockToAcquireOwner == Thread.currentThread())
- {
- // A potential deadlock has been detected
- if (owner == l.getOwner() && l.isLocked())
- {
- LOG.debug("A deadlock has been detected, both threads will be interrupted");
- // The owner did not change so we have a deadlock, so
- // we will interrupt both threads
- owner.interrupt();
- throw new InterruptedException();
- }
- else
- {
- LOG.trace("The owner has changed or the resource is no more locked so we cannot have a deadlock");
- return true;
- }
- }
- currentOwner = lockToAcquireOwner;
- }
- }
-
- /**
- * Internal sub-class of {@link ReentrantLock} needed to be able to register
- * and unregister all the locks automatically
- */
- private class InternalReentrantLock extends ReentrantLock implements Lockable
- {
-
- /**
- * The serial version UID
- */
- private static final long serialVersionUID = 1696442015918441687L;
-
- /**
- * {@inheritDoc}
- */
- public Thread getOwner()
- {
- return super.getOwner();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void lock()
- {
- register(this);
- super.lock();
- unregister(this);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void lockInterruptibly() throws InterruptedException
- {
- register(this);
- try
- {
- checkDeadLock(this);
- super.lockInterruptibly();
- }
- finally
- {
- unregister(this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean tryLock()
- {
- register(this);
- boolean result = super.tryLock();
- unregister(this);
- return result;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException
- {
- register(this);
- try
- {
- checkDeadLock(this);
- return super.tryLock(timeout, unit);
- }
- finally
- {
- unregister(this);
- }
- }
- }
-
- /**
- * Internal sub-class of {@link FutureTask} needed to be able to register
- * and unregister all the tasks automatically
- */
- private class InternalFutureTask extends FutureTask implements Lockable
- {
- /**
- * The current owner of exclusive mode synchronization.
- */
- private final AtomicReference exclusiveOwnerThread = new AtomicReference();
-
- /**
- * {@inheritDoc}
- */
- public InternalFutureTask(Callable callable)
- {
- super(callable);
- }
-
- /**
- * {@inheritDoc}
- */
- public InternalFutureTask(Runnable runnable, V result)
- {
- super(runnable, result);
- }
-
- /**
- * Checks if there is a deadlock, if so it will interrupt the thread waiting for the lock
- */
- private void checkDeadLock()
- {
- try
- {
- LockManager.this.checkDeadLock(this);
- }
- catch (InterruptedException e)
- {
- LOG.debug("An InterruptedException has been caught, but a task must not be interrupted");
- }
- }
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V get() throws InterruptedException, ExecutionException
- {
- register(this);
- checkDeadLock();
- try
- {
- return super.get();
- }
- finally
- {
- unregister(this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
- {
- register(this);
- checkDeadLock();
- try
- {
- return super.get(timeout, unit);
- }
- finally
- {
- unregister(this);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run()
- {
- exclusiveOwnerThread.compareAndSet(null, Thread.currentThread());
- try
- {
- super.run();
- }
- finally
- {
- totalUncompletedTasks.decrementAndGet();
- exclusiveOwnerThread.compareAndSet(Thread.currentThread(), null);
- }
- }
-
- /**
- * Gives the Owner of the task
- */
- public Thread getOwner()
- {
- return exclusiveOwnerThread.get();
- }
-
- /**
- * Indicates whether the task is locked or not, in practice it will be considered as locked if it is not done
- */
- public boolean isLocked()
- {
- return !isDone();
- }
- }
-
- /**
- * Defines a lockable resource
- */
- private static interface Lockable
- {
- /**
- * Gives the owner in case the resource is locked
- */
- Thread getOwner();
-
- /**
- * Indicates whether the resource is locked or not
- */
- boolean isLocked();
- }
-}
diff --git a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/MTInterceptorChainFactory.java b/exo.kernel.container.mt/src/main/java/org/exoplatform/container/MTInterceptorChainFactory.java
deleted file mode 100644
index 701ee9903..000000000
--- a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/MTInterceptorChainFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * This file is part of the Meeds project (https://meeds.io/).
- *
- * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.exoplatform.container;
-
-import org.exoplatform.container.management.ManageableContainer;
-import org.exoplatform.container.spi.After;
-import org.exoplatform.container.spi.Before;
-import org.exoplatform.container.spi.Interceptor;
-import org.exoplatform.container.spi.InterceptorChainFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.ServiceLoader;
-
-/**
- * The "multi-threaded" implementation of a {@link InterceptorChainFactory}. This implementation
- * uses 3 static {@link Interceptor} which are {@link ConcurrentContainerMT},
- * {@link CachingContainer} and {@link ManageableContainer} and uses a list of dynamic {@link Interceptor}
- * that are retrieved thanks to the {@link ServiceLoader}. Then according to the annotations {@link Before}
- * and {@link After} defined on the dynamic {@link Interceptor}, it will define an ordered list of {@link Interceptor}
- * classes which will be used at each next calls of {@link #getInterceptorChain(ExoContainer, ExoContainer)} to
- * re-create the exact same chain of {@link Interceptor}.
-
- */
-public class MTInterceptorChainFactory extends DefaultInterceptorChainFactory
-{
- /**
- * {@inheritDoc}
- */
- protected List getStaticInterceptors(ExoContainer holder, ExoContainer parent)
- {
- List list = new ArrayList(4);
- list.add(new ConcurrentContainerMT(holder, parent));
- list.add(new CachingContainerMT());
- list.add(new ManageableContainer(holder, parent));
- return list;
- }
-}
diff --git a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/Mode.java b/exo.kernel.container.mt/src/main/java/org/exoplatform/container/Mode.java
deleted file mode 100644
index fb11cb2c7..000000000
--- a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/Mode.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/**
- * This file is part of the Meeds project (https://meeds.io/).
- *
- * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.exoplatform.container;
-
-import org.exoplatform.commons.utils.PropertyManager;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * This enumeration defines all the possible mode supported by the kernel.
- *
- */
-public enum Mode {
-
- /**
- * Use this mode when you want to delegate several threads to the kernel to create, initialize and start components.
- */
- MULTI_THREADED,
-
- /**
- * Use this mode when you want to see the kernel automatically fixes dependency issues such as unexpected call to
- * getComponentInstanceOfType() and/or getComponentInstance()
- */
- AUTO_SOLVE_DEP_ISSUES,
-
- /**
- * Indicates whether or not the multi-threading should be disabled on startup complete.
- */
- DISABLE_MT_ON_STARTUP_COMPLETE;
-
- /**
- * The logger
- */
- private static final Log LOG = ExoLogger.getLogger("exo.kernel.container.mt.Mode");
-
- /**
- * The name of the system parameter to indicate that we want to enable the multi-threaded mode of the kernel
- */
- public static final String MULTI_THREADED_PARAM_NAME = "org.exoplatform.container.mt.enabled";
-
- /**
- * The name of the system parameter to indicate that we want to enable the auto solve dependency issues mode
- * of the kernel
- */
- public static final String AUTO_SOLVE_DEP_ISSUES_PARAM_NAME = "org.exoplatform.container.as.enabled";
-
- /**
- * The name of the system parameter to indicate that we want to disable the multi-threaded mode
- * once the {@link TopExoContainer} is fully started
- */
- public static final String DISABLE_MT_ON_STARTUP_COMPLETE_PARAM_NAME = "org.exoplatform.container.dmtosc.enabled";
-
- private static volatile Set MODES;
-
- static void setModes(Mode... modes)
- {
- Set sModes;
- if (modes == null || modes.length == 0)
- {
- sModes = Collections.emptySet();
- }
- else
- {
- sModes = new HashSet(Arrays.asList(modes));
- }
- synchronized (Mode.class)
- {
- MODES = Collections.unmodifiableSet(sModes);
- }
- }
-
- static void clearModes()
- {
- // Clear to enforce reloading the default configuration
- synchronized (Mode.class)
- {
- MODES = null;
- }
- }
-
- /**
- * Indicates whether or not the given mode has been activated
- */
- static boolean hasMode(Mode mode)
- {
- return getModes().contains(mode);
- }
-
- /**
- * Removes the provided modes if they are all defined, does nothing otherwise
- * @param modes the modes to be removed
- * @return true if the modes have been removed, false otherwise.
- */
- static boolean removeModes(Mode... modes)
- {
- if (modes == null || modes.length == 0)
- return false;
- synchronized (Mode.class)
- {
- Set modesSet = new HashSet(getModes());
- for (Mode m : modes)
- {
- if (!modesSet.remove(m))
- {
- return false;
- }
- }
- MODES = Collections.unmodifiableSet(modesSet);
- }
- return true;
- }
-
- private static Set getModes()
- {
- Set modes = MODES;
- if (modes == null)
- {
- synchronized (Mode.class)
- {
- modes = MODES;
- if (modes == null)
- {
- Set sModes = new HashSet();
- String sValue = PropertyManager.getProperty(MULTI_THREADED_PARAM_NAME);
- if ((sValue == null || Boolean.valueOf(sValue)) && Runtime.getRuntime().availableProcessors() > 1)
- {
- sModes.add(MULTI_THREADED);
- if (LOG.isDebugEnabled())
- {
- LOG.debug("The 'multi-threaded' mode of the kernel has been enabled");
- }
- sValue = PropertyManager.getProperty(DISABLE_MT_ON_STARTUP_COMPLETE_PARAM_NAME);
- if (sValue == null || Boolean.valueOf(sValue))
- {
- sModes.add(DISABLE_MT_ON_STARTUP_COMPLETE);
- if (LOG.isDebugEnabled())
- {
- LOG.debug("The 'multi-threaded' mode of the kernel will be disabled once fully started");
- }
- }
- else if (LOG.isDebugEnabled())
- {
- LOG.debug("The 'multi-threaded' mode of the kernel won't be disabled once fully started");
- }
- }
- else if (LOG.isDebugEnabled())
- {
- if (Runtime.getRuntime().availableProcessors() == 1)
- {
- LOG.debug("The 'multi-threaded' mode of the kernel is disabled since you must have more than one processor");
- }
- else
- {
- LOG.debug("The 'multi-threaded' mode of the kernel is disabled");
- }
- }
- sValue = PropertyManager.getProperty(AUTO_SOLVE_DEP_ISSUES_PARAM_NAME);
- if (sValue == null || Boolean.valueOf(sValue))
- {
- sModes.add(AUTO_SOLVE_DEP_ISSUES);
- if (LOG.isDebugEnabled())
- {
- LOG.debug("The 'auto solve dependency issues' mode of the kernel has been enabled");
- }
- }
- else if (LOG.isDebugEnabled())
- {
- LOG.debug("The 'auto solve dependency issues' mode of the kernel is disabled");
- }
- modes = Collections.unmodifiableSet(sModes);
- MODES = modes;
- }
- }
- }
- return modes;
- }
-}
diff --git a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapterMT.java b/exo.kernel.container.mt/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapterMT.java
deleted file mode 100644
index 3bc5485c4..000000000
--- a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/jmx/MX4JComponentAdapterMT.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/**
- * This file is part of the Meeds project (https://meeds.io/).
- *
- * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.exoplatform.container.jmx;
-
-import org.exoplatform.commons.utils.ClassLoading;
-import org.exoplatform.commons.utils.PropertyManager;
-import org.exoplatform.container.ComponentAdapterDependenciesAware;
-import org.exoplatform.container.ComponentTask;
-import org.exoplatform.container.ComponentTaskContext;
-import org.exoplatform.container.ComponentTaskType;
-import org.exoplatform.container.ConcurrentContainer.CreationalContextComponentAdapter;
-import org.exoplatform.container.ConcurrentContainerMT;
-import org.exoplatform.container.CyclicDependencyException;
-import org.exoplatform.container.Dependency;
-import org.exoplatform.container.DependencyStackListener;
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.LockManager;
-import org.exoplatform.container.component.ComponentLifecycle;
-import org.exoplatform.container.component.ComponentPlugin;
-import org.exoplatform.container.configuration.ConfigurationManager;
-import org.exoplatform.container.util.ContainerUtil;
-import org.exoplatform.container.xml.Component;
-import org.exoplatform.container.xml.ExternalComponentPlugins;
-import org.exoplatform.container.xml.InitParams;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-import org.picocontainer.Startable;
-
-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.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.enterprise.context.spi.Context;
-import javax.enterprise.context.spi.CreationalContext;
-import javax.inject.Singleton;
-
-public class MX4JComponentAdapterMT extends MX4JComponentAdapter implements DependencyStackListener,
- ComponentAdapterDependenciesAware
-{
-
- /**
- * Serial Version ID
- */
- private static final long serialVersionUID = -9001193588034229411L;
-
- private transient final AtomicReference> createDependencies =
- new AtomicReference>();
-
- private transient final AtomicReference> initDependencies =
- new AtomicReference>();
-
- /**
- * The task to use to create the component
- */
- private transient final AtomicReference> createTask = new AtomicReference>();
-
- /**
- * The task to use to init the component
- */
- private transient final AtomicReference>> initTasks =
- new AtomicReference>>();
-
- /** . */
- private transient final ConcurrentContainerMT container;
-
- private static final Log LOG = ExoLogger.getLogger("exo.kernel.container.mt.MX4JComponentAdapterMT");
-
- public MX4JComponentAdapterMT(ExoContainer holder, ConcurrentContainerMT container, Object key,
- Class implementation)
- {
- super(holder, container, key, implementation, LockManager.getInstance().createLock());
- this.container = container;
- }
-
- private void addComponentPlugin(List> tasks, Set dependencies, boolean debug,
- List plugins) throws Exception
- {
- if (plugins == null)
- return;
- for (org.exoplatform.container.xml.ComponentPlugin plugin : plugins)
- {
- try
- {
- Class> pluginClass = ClassLoading.forName(plugin.getType(), this);
- List lDependencies = new ArrayList();
- @SuppressWarnings("unchecked")
- Constructor constructor = (Constructor)container.getConstructor(pluginClass, lDependencies);
- dependencies.addAll(lDependencies);
- tasks.add(createPlugin(this, container, pluginClass, debug, plugin, constructor, plugin.getInitParams(),
- lDependencies));
- }
- catch (CyclicDependencyException e)
- {
- throw e;
- }
- catch (Exception ex)
- {
- LOG.error("Failed to instanciate plugin " + plugin.getName() + " for component "
- + getComponentImplementation() + ": " + ex.getMessage(), ex);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- public Collection getCreateDependencies()
- {
- return createDependencies.get();
- }
-
- /**
- * {@inheritDoc}
- */
- public Collection getInitDependencies()
- {
- return initDependencies.get();
- }
-
- /**
- * {@inheritDoc}
- */
- public void callDependency(ComponentTask> task, Dependency dep)
- {
- if (PropertyManager.isDevelopping())
- {
- if (dep.getKey() instanceof String
- || (dep.getKey() instanceof Class && ((Class>)dep.getKey()).isAnnotation()))
- {
- LOG.warn("An unexpected call of getComponentInstance(" + dep.getKey() + "," + dep.getBindType().getName()
- + ") has been detected please add the component in your constructor instead", new Exception(
- "This is the stack trace allowing you to identify where the unexpected "
- + "call of getComponentInstanceOfType has been done"));
- }
- else if (dep.getKey() instanceof Class)
- {
- LOG.warn("An unexpected call of getComponentInstanceOfType(" + ((Class>)dep.getKey()).getName()
- + ") has been detected please add the component in your constructor instead", new Exception(
- "This is the stack trace allowing you to identify where the unexpected "
- + "call of getComponentInstanceOfType has been done"));
- }
- }
- if (dep.getKey().equals(getComponentKey()))
- {
- return;
- }
- if (task.getType() == ComponentTaskType.CREATE)
- {
- getCreateDependencies().add(dep);
- }
- else if (task.getType() == ComponentTaskType.INIT)
- {
- getInitDependencies().add(dep);
- }
- container.getComponentTaskContext().checkDependency(dep.getKey(), task.getType());
- }
-
- /**
- * {@inheritDoc}
- */
- @SuppressWarnings("unchecked")
- protected ComponentTask getCreateTask()
- {
- Component component = null;
- String componentKey;
- InitParams params = null;
- boolean debug = false;
-
- // Get the component
- Object key = getComponentKey();
- if (key instanceof String)
- componentKey = (String)key;
- else
- componentKey = ((Class>)key).getName();
- try
- {
- ConfigurationManager manager =
- (ConfigurationManager)exocontainer.getComponentInstanceOfType(ConfigurationManager.class);
- component = manager == null ? null : manager.getComponent(componentKey);
- if (component != null)
- {
- params = component.getInitParams();
- debug = component.getShowDeployInfo();
- }
- if (debug)
- LOG.debug("==> get constructor of the component : " + getComponentImplementation());
- List lDependencies = new ArrayList();
- Constructor> constructor = container.getConstructor(getComponentImplementation(), lDependencies);
- setCreateDependencies(lDependencies);
- if (debug)
- LOG.debug("==> create component : " + getComponentImplementation());
- return (ComponentTask)container.createComponentTask(constructor, params, lDependencies, this);
- }
- catch (Exception e)
- {
- String msg = "Cannot instantiate component " + getComponentImplementation();
- if (component != null)
- {
- msg =
- "Cannot instantiate component key=" + component.getKey() + " type=" + component.getType() + " found at "
- + component.getDocumentURL();
- }
- throw new RuntimeException(msg, e);
- }
- }
-
- protected void setCreateDependencies(List lDependencies)
- {
- if (createDependencies.get() == null)
- {
- createDependencies.compareAndSet(null, new CopyOnWriteArraySet(lDependencies));
- }
- }
-
- /**
- * {@inheritDoc}
- */
- protected Collection> getInitTasks()
- {
- Component component = null;
- String componentKey;
- boolean debug = false;
-
- // Get the component
- Object key = getComponentKey();
- if (key instanceof String)
- componentKey = (String)key;
- else
- componentKey = ((Class>)key).getName();
- try
- {
- ConfigurationManager manager =
- (ConfigurationManager)exocontainer.getComponentInstanceOfType(ConfigurationManager.class);
- component = manager == null ? null : manager.getComponent(componentKey);
- if (component != null)
- {
- debug = component.getShowDeployInfo();
- }
- List> tasks = new ArrayList>();
- Set dependencies = new HashSet();
-
- final Class implementationClass = getComponentImplementation();
- boolean isSingleton = this.isSingleton;
- boolean isInitialized = this.isInitialized;
- if (debug)
- LOG.debug("==> create component : " + implementationClass.getName());
- boolean hasInjectableConstructor = !isSingleton || ContainerUtil.hasInjectableConstructor(implementationClass);
- boolean hasOnlyEmptyPublicConstructor =
- !isSingleton || ContainerUtil.hasOnlyEmptyPublicConstructor(implementationClass);
- if (hasInjectableConstructor || hasOnlyEmptyPublicConstructor)
- {
- // There is at least one constructor JSR 330 compliant or we already know
- // that it is not a singleton such that the new behavior is expected
- List lDependencies = new ArrayList();
- boolean isInjectPresent = container.initializeComponent(implementationClass, lDependencies, tasks, this);
- dependencies.addAll(lDependencies);
- isSingleton = manageScope(isSingleton, isInitialized, hasInjectableConstructor, isInjectPresent);
- }
- else if (!isInitialized)
- {
- // The adapter has not been initialized yet
- // The old behavior is expected as there is no constructor JSR 330 compliant
- isSingleton = this.isSingleton = true;
- scope.set(Singleton.class);
- }
- if (component != null && component.getComponentPlugins() != null)
- {
- addComponentPlugin(tasks, dependencies, debug, component.getComponentPlugins());
- }
- ExternalComponentPlugins ecplugins =
- manager == null ? null : manager.getConfiguration().getExternalComponentPlugins(componentKey);
- if (ecplugins != null)
- {
- addComponentPlugin(tasks, dependencies, debug, ecplugins.getComponentPlugins());
- }
- initDependencies.compareAndSet(null, new CopyOnWriteArraySet(dependencies));
- tasks.add(new ComponentTask("initialize component " + getComponentImplementation().getName(), container,
- this, ComponentTaskType.INIT)
- {
- public Void execute(CreationalContextComponentAdapter> cCtx) throws Exception
- {
- // check if component implement the ComponentLifecycle
- if (cCtx.get() instanceof ComponentLifecycle && exocontainer instanceof ExoContainer)
- {
- ComponentLifecycle lc = (ComponentLifecycle)cCtx.get();
- lc.initComponent((ExoContainer)exocontainer);
- }
- return null;
- }
- });
- if (!isInitialized)
- {
- this.isInitialized = true;
- }
- return tasks;
- }
- catch (Exception e)
- {
- String msg = "Cannot initialize component " + getComponentImplementation();
- if (component != null)
- {
- msg =
- "Cannot initialize component key=" + component.getKey() + " type=" + component.getType() + " found at "
- + component.getDocumentURL();
- }
- throw new RuntimeException(msg, e);
- }
- }
-
- private ComponentTask createPlugin(final MX4JComponentAdapterMT caller,
- final ConcurrentContainerMT exocontainer, final Class> pluginClass, final boolean debug,
- final org.exoplatform.container.xml.ComponentPlugin plugin, final Constructor constructor, InitParams params,
- List lDependencies) throws Exception
- {
- final Object[] args = exocontainer.getArguments(constructor, params, lDependencies);
- return new ComponentTask("create/add plugin " + plugin.getName() + " for component "
- + getComponentImplementation().getName(), exocontainer, caller, ComponentTaskType.INIT)
- {
- public Void execute(final CreationalContextComponentAdapter> cCtx) throws Exception
- {
- try
- {
- getContainer().loadArguments(args);
- ComponentPlugin cplugin = (ComponentPlugin)constructor.newInstance(args);
- cplugin.setName(plugin.getName());
- cplugin.setDescription(plugin.getDescription());
- Class> clazz = getComponentImplementation();
-
- final Method m = getSetMethod(clazz, plugin.getSetMethod(), pluginClass);
- if (m == null)
- {
- LOG.error("Cannot find the method '" + plugin.getSetMethod()
- + "' that has only one parameter of type '" + pluginClass.getName() + "' in the class '"
- + clazz.getName() + "'.");
- return null;
- }
- final Object[] params = {cplugin};
-
- m.invoke(cCtx.get(), params);
-
- if (debug)
- LOG.debug("==> add component plugin: " + cplugin);
-
- cplugin.setName(plugin.getName());
- cplugin.setDescription(plugin.getDescription());
- return null;
- }
- catch (InvocationTargetException e)
- {
- if (e.getCause() instanceof Exception)
- {
- throw (Exception)e.getCause();
- }
- throw e;
- }
- }
- };
- }
-
- protected T createInstance(final Context ctx)
- {
- T result = ctx.get(this);
- if (result != null)
- {
- return result;
- }
- return create(new Callable()
- {
- public T call() throws Exception
- {
- try
- {
- return ctx.get(MX4JComponentAdapterMT.this, container. addComponentToCtx(getComponentKey()));
- }
- finally
- {
- container.removeComponentFromCtx(getComponentKey());
- }
- }
- });
- }
-
- /**
- * Must be used to create Singleton or Prototype only
- */
- protected T create()
- {
- return create(new Callable()
- {
- public T call() throws Exception
- {
- return doCreate();
- }
- });
- }
-
- /**
- * Must be used to create Singleton or Prototype only
- */
- protected T doCreate()
- {
- return doCreate(false);
- }
-
- /**
- * Must be used to create Singleton or Prototype only
- */
- protected T doCreate(boolean useSharedMemory)
- {
- if (instance_ != null)
- {
- return instance_;
- }
- boolean toBeLocked = isSingleton;
- boolean skipFinally = false;
- try
- {
- CreationalContextComponentAdapter ctx;
- if (toBeLocked)
- {
- if (useSharedMemory)
- {
- T result = container. getComponentFromSharedMemory(getComponentKey());
- if (result != null)
- {
- LOG.debug("The value could be found from the shared memory");
- skipFinally = true;
- return result;
- }
- LOG.debug("The value could not be found from the shared memory");
- }
- if (!lock.tryLock())
- {
- // The lock has already been acquired, let's make sure that we
- // don't have any deadlocks
- lock.lockInterruptibly();
- }
- ctx = container. addComponentToCtx(getComponentKey());
- }
- else
- {
- // Don't add to context non singleton
- skipFinally = true;
- ctx = new CreationalContextComponentAdapter();
- }
- return create(ctx);
- }
- catch (InterruptedException e)
- {
- // We make sure that the state of the Thread is back to normal
- Thread.interrupted();
- skipFinally = true;
- LOG.debug("A deadlock has been detected, let's retry using the shared memory");
- return doCreate(true);
- }
- finally
- {
- if (!skipFinally)
- {
- lock.unlock();
- container.removeComponentFromCtx(getComponentKey());
- }
- }
- }
-
- private T create(Callable mainCreateTask)
- {
- ComponentTaskContext ctx = container.getComponentTaskContext();
- try
- {
- loadTasks();
- loadDependencies(ctx);
- return mainCreateTask.call();
- }
- catch (CyclicDependencyException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("Cannot create component " + getComponentImplementation(), e);
- }
- finally
- {
- if (ctx == null)
- {
- container.setComponentTaskContext(null);
- }
- }
- }
-
- private void loadDependencies(ComponentTaskContext ctx) throws Exception
- {
- ComponentTaskContext createCtx = ctx;
- if (createCtx == null)
- {
- createCtx = new ComponentTaskContext(getComponentKey(), ComponentTaskType.CREATE);
- container.setComponentTaskContext(createCtx);
- }
- else if (!createCtx.isLast(getComponentKey()))
- {
- createCtx = createCtx.addToContext(getComponentKey());
- container.setComponentTaskContext(createCtx);
- }
- container.loadDependencies(getComponentKey(), createCtx, getCreateDependencies(), ComponentTaskType.CREATE);
- }
-
- /**
- * {@inheritDoc}
- */
- public T create(CreationalContext creationalContext)
- {
- CreationalContextComponentAdapter ctx = (CreationalContextComponentAdapter)creationalContext;
- // Avoid to create duplicate instances if it is called at the same time by several threads
- if (instance_ != null)
- return instance_;
- else if (ctx.get() != null)
- return ctx.get();
- ComponentTaskContext taskCtx = container.getComponentTaskContext();
- boolean isRoot = taskCtx.isRoot();
- if (!isRoot)
- {
- container.setComponentTaskContext(taskCtx = taskCtx.setLastTaskType(ComponentTaskType.CREATE));
- }
- try
- {
- ComponentTask task = createTask.get();
- T result = task.call(ctx);
- if (instance_ != null)
- {
- // Avoid instantiating twice the same component in case of a cyclic reference due
- // to component plugins
- return instance_;
- }
- else if (ctx.get() != null)
- return ctx.get();
-
- ctx.push(result);
- }
- catch (CyclicDependencyException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- throw new RuntimeException("Cannot create component " + getComponentImplementation(), e);
- }
- if (isRoot)
- {
- container.setComponentTaskContext(taskCtx =
- taskCtx.resetDependencies(getComponentKey(), ComponentTaskType.INIT));
- }
- else
- {
- container.setComponentTaskContext(taskCtx = taskCtx.setLastTaskType(ComponentTaskType.INIT));
- }
-
- Collection> tasks = initTasks.get();
- ComponentTask task = null;
- try
- {
- if (tasks != null && !tasks.isEmpty())
- {
- container.loadDependencies(getComponentKey(), taskCtx, getInitDependencies(), ComponentTaskType.INIT);
- for (Iterator> it = tasks.iterator(); it.hasNext();)
- {
- task = it.next();
- task.call(ctx);
- task = null;
- }
- }
- if (instance_ != null)
- {
- return instance_;
- }
- else if (instance_ == null && isSingleton)
- {
- // In case of cyclic dependency the component could be already initialized
- // so we need to recheck the state
- instance_ = ctx.get();
- }
- }
- catch (CyclicDependencyException e)
- {
- throw e;
- }
- catch (Exception e)
- {
- if (task != null)
- {
- throw new RuntimeException("Cannot " + task.getName() + " for the component "
- + getComponentImplementation(), e);
- }
- throw new RuntimeException("Cannot initialize component " + getComponentImplementation(), e);
- }
- if (ctx.get() instanceof Startable && exocontainer.canBeStopped())
- {
- try
- {
- // Start the component if the container is already started
- ((Startable)ctx.get()).start();
- }
- catch (Exception e)
- {
- throw new RuntimeException("Cannot auto-start component " + getComponentImplementation(), e);
- }
- }
- return ctx.get();
- }
-
- private void loadTasks()
- {
-
- if (createTask.get() == null)
- {
- try
- {
- createTask.compareAndSet(null, getCreateTask());
- }
- catch (RuntimeException e)
- {
- throw new RuntimeException("Cannot get the create task of the component " + getComponentImplementation(), e);
- }
- }
- if (initTasks.get() == null)
- {
- try
- {
- initTasks.compareAndSet(null, getInitTasks());
- }
- catch (RuntimeException e)
- {
- throw new RuntimeException("Cannot get the init tasks of the component " + getComponentImplementation(), e);
- }
- }
- }
-}
diff --git a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/management/ManageableComponentAdapterFactoryMT.java b/exo.kernel.container.mt/src/main/java/org/exoplatform/container/management/ManageableComponentAdapterFactoryMT.java
deleted file mode 100644
index ca25550fc..000000000
--- a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/management/ManageableComponentAdapterFactoryMT.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * This file is part of the Meeds project (https://meeds.io/).
- *
- * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.exoplatform.container.management;
-
-import org.exoplatform.container.ConcurrentContainerMT;
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.spi.ComponentAdapter;
-import org.exoplatform.container.spi.ComponentAdapterFactory;
-import org.exoplatform.container.spi.ContainerException;
-
-public class ManageableComponentAdapterFactoryMT implements ComponentAdapterFactory
-{
-
- /** . */
- private final ExoContainer holder;
-
- /** . */
- private final ConcurrentContainerMT container;
-
- public ManageableComponentAdapterFactoryMT(ExoContainer holder, ConcurrentContainerMT container)
- {
- this.holder = holder;
- this.container = container;
- }
-
- public ComponentAdapter createComponentAdapter(Object componentKey, Class componentImplementation)
- throws ContainerException
- {
- return new ManageableComponentAdapterMT(holder, container, componentKey, componentImplementation);
- }
-}
diff --git a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/management/ManageableComponentAdapterMT.java b/exo.kernel.container.mt/src/main/java/org/exoplatform/container/management/ManageableComponentAdapterMT.java
deleted file mode 100644
index 6742594e4..000000000
--- a/exo.kernel.container.mt/src/main/java/org/exoplatform/container/management/ManageableComponentAdapterMT.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/**
- * This file is part of the Meeds project (https://meeds.io/).
- *
- * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.exoplatform.container.management;
-
-import org.exoplatform.container.ConcurrentContainerMT;
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.jmx.MX4JComponentAdapterMT;
-import org.exoplatform.container.spi.Container;
-import org.exoplatform.management.spi.ManagementProvider;
-import org.exoplatform.services.log.ExoLogger;
-import org.exoplatform.services.log.Log;
-
-import java.lang.annotation.Annotation;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import javax.enterprise.context.Dependent;
-import javax.enterprise.context.spi.CreationalContext;
-
-public class ManageableComponentAdapterMT extends MX4JComponentAdapterMT
-{
-
- /**
- * The serial version UID
- */
- private static final long serialVersionUID = 5165449586256525854L;
-
- /** . */
- private static final Log LOG = ExoLogger.getLogger("exo.kernel.container.mt.ManageableComponentAdapterMT");
-
- /** . */
- private final AtomicBoolean registered = new AtomicBoolean();
-
- public ManageableComponentAdapterMT(ExoContainer holder, ConcurrentContainerMT container, Object key,
- Class implementation)
- {
- super(holder, container, key, implementation);
- }
-
- protected void register(Container co, Object instance)
- {
- if (registered.compareAndSet(false, true))
- {
- do
- {
- if (co instanceof ManageableContainer)
- {
- break;
- }
- }
- while ((co = co.getSuccessor()) != null);
- if (co instanceof ManageableContainer)
- {
- ManageableContainer container = (ManageableContainer)co;
- if (container.managementContext != null)
- {
- // Register the instance against the management context
- if (LOG.isDebugEnabled())
- LOG.debug("==> add " + instance + " to a mbean server");
- container.managementContext.register(instance);
-
- // Register if it is a management provider
- if (instance instanceof ManagementProvider)
- {
- ManagementProvider provider = (ManagementProvider)instance;
- container.addProvider(provider);
- }
- }
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public T create(CreationalContext creationalContext)
- {
- T instance = super.create(creationalContext);
- Class extends Annotation> scope = null;
- if (instance != null && (((scope = getScope()) != null && !scope.equals(Dependent.class))) || isSingleton())
- {
- register(exocontainer, instance);
- }
- return instance;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void destroy(T instance, CreationalContext creationalContext)
- {
- try
- {
- Container co = exocontainer;
- do
- {
- if (co instanceof ManageableContainer)
- {
- break;
- }
- }
- while ((co = co.getSuccessor()) != null);
- if (co instanceof ManageableContainer)
- {
- ManageableContainer container = (ManageableContainer)co;
- if (container.managementContext != null)
- {
- // UnRegister the instance against the management context
- if (LOG.isDebugEnabled())
- LOG.debug("==> remove " + instance + " from a mbean server");
- container.managementContext.unregister(instance);
- }
- }
- creationalContext.release();
- }
- catch (Exception e)
- {
- LOG.error("Could not destroy the instance " + instance + ": " + e.getMessage());
- }
- }
-}
\ No newline at end of file
diff --git a/exo.kernel.container.mt/src/main/resources/META-INF/services/org.exoplatform.container.spi.InterceptorChainFactory b/exo.kernel.container.mt/src/main/resources/META-INF/services/org.exoplatform.container.spi.InterceptorChainFactory
deleted file mode 100644
index 81f9c8013..000000000
--- a/exo.kernel.container.mt/src/main/resources/META-INF/services/org.exoplatform.container.spi.InterceptorChainFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.exoplatform.container.MTInterceptorChainFactory
\ No newline at end of file
diff --git a/exo.kernel.container.mt/src/test/java/org/exoplatform/container/TestExoContainerMT.java b/exo.kernel.container.mt/src/test/java/org/exoplatform/container/TestExoContainerMT.java
deleted file mode 100644
index c9e8e5e81..000000000
--- a/exo.kernel.container.mt/src/test/java/org/exoplatform/container/TestExoContainerMT.java
+++ /dev/null
@@ -1,392 +0,0 @@
-/**
- * This file is part of the Meeds project (https://meeds.io/).
- *
- * Copyright (C) 2020 - 2025 Meeds Association contact@meeds.io
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.exoplatform.container;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import org.exoplatform.container.component.BaseComponentPlugin;
-import org.exoplatform.container.jmx.AbstractTestContainer;
-import org.exoplatform.container.jmx.MX4JComponentAdapterMT;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import org.picocontainer.Startable;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Provider;
-import javax.inject.Qualifier;
-import javax.inject.Singleton;
-
-@RunWith(Parameterized.class)
-public class TestExoContainerMT extends TestExoContainer
-{
- private Mode[] modes;
- public TestExoContainerMT(Mode... modes)
- {
- this.modes = modes;
- }
-
- @Before
- public void setUp()
- {
- Mode.setModes(modes);
- }
-
- @After
- public void tearDown()
- {
- Mode.clearModes();
- }
-
- @Parameters
- public static List data()
- {
- return Arrays.asList(new Object[][]{{null}, {new Mode[]{Mode.MULTI_THREADED}},
- {new Mode[]{Mode.MULTI_THREADED, Mode.DISABLE_MT_ON_STARTUP_COMPLETE}}, {new Mode[]{Mode.AUTO_SOLVE_DEP_ISSUES}},
- {new Mode[]{Mode.MULTI_THREADED, Mode.AUTO_SOLVE_DEP_ISSUES}},
- {new Mode[]{Mode.MULTI_THREADED, Mode.AUTO_SOLVE_DEP_ISSUES, Mode.DISABLE_MT_ON_STARTUP_COMPLETE}}});
- }
-
- @Test
- public void testBadCyclicRef() throws Exception
- {
- RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef");
- try
- {
- container.getComponentInstanceOfType(TestExoContainer.A1.class);
- fail("A CyclicDependencyException was expected");
- }
- catch (CyclicDependencyException e)
- {
- // expected exception
- }
- }
-
- @Test
- public void testBadCyclicRef2() throws Exception
- {
- try
- {
- AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef2");
- }
- catch (CyclicDependencyException e)
- {
- // expected exception
- }
- }
-
- @Test
- public void testBadCyclicRef3() throws Exception
- {
- RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef3");
- try
- {
- container.getComponentInstanceOfType(A1.class);
- fail("A CyclicDependencyException was expected");
- }
- catch (CyclicDependencyException e)
- {
- // expected exception
- }
- }
-
- @Test
- public void testBadCyclicRef4() throws Exception
- {
- try
- {
- AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef4");
- }
- catch (CyclicDependencyException e)
- {
- // expected exception
- }
- }
-
- public static class A1
- {
- public B1 b;
-
- public A1(ExoContainerContext ctx)
- {
- this.b = ctx.getContainer().getComponentInstanceOfType(B1.class);
- }
- }
-
- public static class B1
- {
- public A1 a;
-
- public B1(ExoContainerContext ctx)
- {
- this.a = ctx.getContainer().getComponentInstanceOfType(A1.class);
- }
- }
-
- public static class A2 implements Startable
- {
- public B2 b;
-
- public A2(ExoContainerContext ctx)
- {
- this.b = ctx.getContainer().getComponentInstanceOfType(B2.class);
- }
-
- public void start()
- {
- }
-
- public void stop()
- {
- }
- }
-
- public static class B2
- {
- public A2 a;
-
- public B2(ExoContainerContext ctx)
- {
- this.a = ctx.getContainer().getComponentInstanceOfType(A2.class);
- }
- }
-
- @Test
- public void testBadCyclicRef5() throws Exception
- {
- RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef5");
- try
- {
- container.getComponentInstanceOfType(A3.class);
- fail("A CyclicDependencyException was expected");
- }
- catch (CyclicDependencyException e)
- {
- // expected exception
- }
- }
-
- @Test
- public void testBadCyclicRef6() throws Exception
- {
- try
- {
- AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testBadCyclicRef6");
- }
- catch (CyclicDependencyException e)
- {
- // expected exception
- }
- }
-
- @Singleton
- public static class A3
- {
- public B3 b;
-
- @Inject
- public A3(Provider p)
- {
- this.b = p.get();
- }
- }
-
- @Singleton
- public static class B3
- {
- public A3 a;
-
- @Inject
- public B3(Provider p)
- {
- this.a = p.get();
- }
- }
-
- @Singleton
- public static class A4 implements Startable
- {
- public B4 b;
-
- @Inject
- public A4(Provider p)
- {
- this.b = p.get();
- }
-
- public void start()
- {
- }
-
- public void stop()
- {
- }
- }
-
- @Singleton
- public static class B4
- {
- public A4 a;
-
- @Inject
- public B4(Provider p)
- {
- this.a = p.get();
- }
- }
-
- @Test
- public void testAutoSolveDepIssues()
- {
- RootContainer container = AbstractTestContainer.createRootContainer(getClass(), "test-exo-container-mt.xml", "testAutoSolveDepIssues");
- MX4JComponentAdapterMT adapter1 =
- (MX4JComponentAdapterMT)container.getComponentAdapterOfType(ASDI_1.class);
- MX4JComponentAdapterMT adapter2 =
- (MX4JComponentAdapterMT)container.getComponentAdapterOfType(ASDI_2.class);
- MX4JComponentAdapterMT