I added some code to my WAR project to use javax.enterprise.concurrent.ManagedThreadFactory and I'm now getting a NoClassDefFoundError. I've attached the error message and my Maven pom change. I'm using WebLogic 12c with Java 1.7.
]] Root cause of ServletException.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myComponent' defined in class path resource [my/package/bean.xml]: Cannot resolve reference to bean 'careCoordinatorRecipientListComponentRouter' while setting bean property 'inboundRouter'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myComponent': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.enterprise.concurrent.ManagedThreadFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)}
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1325)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
Truncated. see log file for complete stacktrace
Caused By: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'careCoordinatorRecipientListComponentRouter': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.enterprise.concurrent.ManagedThreadFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)}
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:300)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
Truncated. see log file for complete stacktrace
Caused By: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.enterprise.concurrent.ManagedThreadFactory] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@javax.annotation.Resource(shareable=true, mappedName=, description=, name=, type=class java.lang.Object, authenticationType=CONTAINER, lookup=)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:920)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:789)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:703)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:431)
at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
Truncated. see log file for complete stacktrace
Maven change:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
My class that's using this code:
public class AsynchronousLinkedComponentRouter implements
MessageDispatcher<Object, Object> {
/**
* The components reference.
*
* @uml.property name="component"
* @uml.associationEnd
*/
private List<Component<Object, Object>> components;
/**
* Logger for this class.
*/
private static final Log LOG = LogFactory
.getLog(AsynchronousLinkedComponentRouter.class);
protected ConcurrentHashMap<String, Object> threadResultsMap;
protected ConcurrentHashMap<String, ComponentException> componentExceptionsInThreads;
@Resource
private javax.enterprise.concurrent.ManagedThreadFactory threadFactory;
/**
* Set the components.
*
* @param theComponent
* the component reference.
*/
@Required
public void setComponents(final List<Component<Object, Object>> components) {
this.components = components;
}
/**
* Route the message to the component.
*
* @param message
* the message
* @return the output after the component has processed the message
* @throws RouterException
* if an error occurred when routing the message
*/
@Override
public Object route(final Object message) throws RouterException {
try {
threadResultsMap = new ConcurrentHashMap<String, Object>();
List<Thread> producerThreads = new ArrayList<Thread>();
for (final Component<Object, Object> component : this.components) {
AsychronousMessageProcessorTask ampTask = this.new AsychronousMessageProcessorTask(
component, message);
Thread producerThread = threadFactory.newThread(ampTask);
producerThread.setName("Parent thread: "
+ Thread.currentThread().getName() + " for component: "
+ component.getName());
producerThread.start();
producerThreads.add(producerThread);
}
LOG.info("Created the producer threads, waiting to join the threads.");
try {
for (Thread thread : producerThreads) {
thread.join();
}
} catch (InterruptedException e) {
throw new RouterException("Interruption while joining producer threads",e);
}
LOG.info("Joined all producer threads");
if (componentExceptionsInThreads.size() > 0) {
LOG.info("Detected exceptions thrown in "
+ String.valueOf(componentExceptionsInThreads.size())
+ " producer thread(s).");
String oneExceptionKey = null;
for (String k : componentExceptionsInThreads.keySet()) {
LOG.error(componentExceptionsInThreads.get(k));
oneExceptionKey = k;
}
// We can only throw one of the (possibly multiple) ComponentExceptions
// The selected one to throw is not guaranteed to be the first.
throw (componentExceptionsInThreads.get(oneExceptionKey));
}
List<Object> resultsList = new ArrayList<Object>(threadResultsMap.values());
return resultsList;
} catch (final ComponentException ex) {
throw new RouterException(ex);
}
}
private class AsychronousMessageProcessorTask implements Runnable {
private Component<Object, Object> component;
private Object message;
public AsychronousMessageProcessorTask(Component<Object, Object> component,
final Object message) {
this.component = component;
this.message = message;
}
public void run() {
try {
threadResultsMap.put(component.getName(),
component.processInbound(message));
} catch (ComponentException e) {
componentExceptionsInThreads.put(component.getName(), e);
}
}
}
}