Beans loaded through CDI extensions sometimes not available

126 views
Skip to first unread message

Eduardo

unread,
Jan 20, 2012, 2:28:07 PM1/20/12
to CDI Advocate
Hi guys,

I'm trying to load some beans through a CDI extension, and such beans
come from jar files. Sometimes they are available on JSF pages. But,
if I reboot jboss (version 6.1) the beans are not available anymore.
After more reboots the bean get available again. I pretty sure that
the extension load correctly the bean classes whenever the CDI
container initializes.

I wrote the CDI extension according to the example available at:
http://in.relation.to/Bloggers/AnotherNicePortableExtension

Can anyone tell what I'm missing here?

Below, I list the code:

MyExtension

List<Class<?>> getBeanClasses() throws IOException,
ClassNotFoundException,
InstantiationException, IllegalAccessException {

PluginLoader loader = new PluginLoader();
PluginPathResolver resolver = new WebPathResolver();
File file = new File(resolver.getPluginRepository().
concat("sequi.plugins.projectlog-0.0.1-
SNAPSHOT.jar"));

PluginBundle bundle = loader.load(file);
loader.installView(file, resolver, bundle.getName());
return bundle.getManagedBeans();
}

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd,
BeanManager bm) throws IOException, ClassNotFoundException,
InstantiationException, IllegalAccessException {


System.out.println("---------- loading the beans -------------");

if(getBeanClasses() == null){
System.out.println("no classes to load.");
return;
}


for ( final Class c: getBeanClasses() ) {

//use this to read annotations of the class
AnnotatedType at = bm.createAnnotatedType(c);

//use this to create the class and inject dependencies
final InjectionTarget it = bm.createInjectionTarget(at);

abd.addBean( new Bean() {

@Override
public Class<?> getBeanClass() {
return c;
}

@Override
public Set<InjectionPoint> getInjectionPoints() {
return it.getInjectionPoints();
}

@Override
public String getName() {
//hardcoded beacause I'll load a known class
//for testing the approach
return "myDateUtils";
}

@Override
public Set<Annotation> getQualifiers() {
Set<Annotation> qualifiers = new
HashSet<Annotation>();
qualifiers.add( new AnnotationLiteral<Default>()
{} );
qualifiers.add( new AnnotationLiteral<Any>() {} );
return qualifiers;
}

@Override
public Class<? extends Annotation> getScope() {
//return Dependent.class;
return SessionScoped.class;
}

@Override
public Set<Class<? extends Annotation>>
getStereotypes() {
return Collections.emptySet();
}

@Override
public Set<Type> getTypes() {
Set<Type> types = new HashSet<Type>();
types.add(c);
types.add(Object.class);
return types;
}

@Override
public boolean isAlternative() {
return false;
}

@Override
public boolean isNullable() {
return false;
}

@Override
public Object create(CreationalContext ctx) {
Object instance = it.produce(ctx);
it.inject(instance, ctx);
it.postConstruct(instance);
return instance;
}

@Override
public void destroy(Object instance, CreationalContext
ctx) {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}

} );
}

}


----------------------------------------------------------------------------------------------
Class that should be dynamically load into CDI:

@Named("myDateUtils")
public class DateUtils {

public String getToday(){
<...>
return the date formatted string..
}


@PostConstruct
public void showMessage(){
System.out.println("Class post construct method!")
}

}

--------------------------------------------------------------------------------------------------------------------------
Simple facelets page using the bean:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
....
.../>
<h1>Adicionar diário</h1>


<h:outputText value="new.xhtml" /><br/>
<h:outputText value="#{myDateUtils.today}"/>

</html>
Reply all
Reply to author
Forward
0 new messages