[Design the new POJO MicroContainer] - Re: Dependencies from scoped to global
by kabir.khan@jboss.com
I think/hope this is the last hurdle for me to get scoped aop working. Deploy works fine, undeploy doesn't as described above.
Here's a quick hack for you :-) For my use case the scoped bean is an aop interceptor, and the global is a bean that gets injected into the interceptor. The interceptor is installed into a scoped controller by the aop deployer with a unique prefix/name. So we could look at the child controllers for a bean with that name if this call returns null.
| ControllerContext dependent = getContext(item.getName(), null);
|
This would work for aop, but could break other things if names are not unique. You did however recommend unique names due to shortcomings in AbstractController.uninstall(), so "other things" using scoping might be broken anyway?
I'm not familiar with this part of the code, so the rest of this post is me guessing :-) Who populates DependencyInfo.dependsOnMe? I would assume it happens when describing the side who has the dependency? i.e. the scoped bean who has a dependency on the global one? If that is correct, could/should not the controller be known for the dependencies?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4171271#4171271
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4171271
17 years, 7 months
[Design of POJO Server] - Re: Using AnnotationEnvironment in Seam
by alesj
"pete.muir(a)jboss.org" wrote :
| 1) We currently only scan artifacts which have seam.properties (or META-INF/seam.properties or META-INF/components.xml). This includes:
|
| * WEB-INF/classes
| * Any lib in WEB-INF/lib
| * Any lib declared in the manifest
| * Any lib declared in the ear (e.g. in lib/, declared as an ejb in application.xml, declared in the manifest)
| * Any lib in our parent classloaders
|
| How do we replicate this behaviour?
|
Basically you're saying you scan the whole classpath,
but only do real lookup from the root of those deployments/classpath entries
that have some Seam specific resource present?
The AnnEnv handles this already since it does lookup at the classloading layer,
we could perhaps exclude deployments that don't contain any Seam specific resource before we actually do some reading from AnnEnv.
"pete.muir(a)jboss.org" wrote :
| 2) We have other deployment handlers
|
| e.g. org.jboss.seam.deployment.ComponentsXmlDeploymentHandler::handle
|
| public void handle(String name, ClassLoader classLoader)
| | {
| | if (name.endsWith(".component.xml") || name.endsWith("/components.xml"))
| | {
| | // we want to skip over known meta-directories since Seam will
| | // auto-load these without a scan
| | if (!name.startsWith("WEB-INF/") && !name.startsWith("META-INF/"))
| | {
| | resources.add(name);
| | }
| | }
| |
| | }
|
| For this approach to decrease deployment time, we need to not scan at all (or scan a very limited set of files), so can we get this metadata (files, based on their filename) from the MC?
|
| If you want to look at the handlers which are relevant:
|
| * org.jboss.seam.deployment.AnnotationDeploymentHandler (support for users to specify their own annotations to handle, the AnnotationEnv backed version can just be a facade)
| * org.jboss.seam.deployment.ComponentDeploymentHandler
| * org.jboss.seam.deployment.ComponentsXmlDeploymentHandler
| * org.jboss.seam.deployment.DotPageDotXmlDeploymentHandler
| * org.jboss.seam.deployment.NamespaceDeploymentHandler
| * org.jboss.seam.bpm.PageflowDeploymentHandler
|
We could add this in a similar way we do annotation scanning -
as ResourceVisitor on Module.
Or we could visit deployment's root,
excluding deployments metadata locations.
The result should be then put as attachment to deployment unit's attachments.
Let me know what exactly you need,
and I'll try to put the code into seam-int/microcontainer module.
Or you can do it, and learn a few tricks about MC. :-)
"pete.muir(a)jboss.org" wrote :
| 3) For the future, can we add support for metaannotations support? This will make it supereasy to use for WB.
|
| E.g.
|
| public interface AnnotationEnvironment
| | {
| | ...
| | boolean hasClassMetaAnnotatedWith(Class<? extends Annotation> annotation);
| |
| | // etc.
| |
| annotationEnvironment.hasClassMetaAnnotatedWith(javax.webbeans.DeploymentType.class);
|
You mean this:
| @DeploymentType
| public @interface SomeType {}
|
| @SomeType
| public class MyTypeImpl {}
|
Where you would like to get MyTypeImpl class?
Should be easy to add.
I'll have a look.
"pete.muir(a)jboss.org" wrote :
| 4) How does it handle exceptions loading classes? Throw them for us to catch?
|
AnnEnv doesn't load classes. ;-)
But it will throw RuntimeException when you ask for it and it fails.
Annotation scanning deployer by default doesn't fail if it has some problems
reading the annotations. But this is optional.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4171269#4171269
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4171269
17 years, 7 months
[Design the new POJO MicroContainer] - Re: Dependencies from scoped to global
by alesj
"kabir.khan(a)jboss.com" wrote :
| Unless you know what I have said above is wrong, I can try to reproduce with a test case.
I know what the problem is.
The problem is simple :-),
it's the solution that is not that trivial. :-(
The issue is that when you do install,
the underlying controller used in that dependency item resolution is scoped,
but when you do uninstall
| Set<DependencyItem> dependsOnMe = dependencies.getDependsOnMe(null);
| if (dependsOnMe.isEmpty() == false)
| {
| for (DependencyItem item : dependsOnMe)
| {
| if (item.isResolved())
| {
| ControllerState dependentState = item.getDependentState();
| if (dependentState == null || dependentState.equals(fromState))
| {
| if (item.unresolved(this))
| {
| ControllerContext dependent = getContext(item.getName(), null);
| if (dependent != null)
| {
| ControllerState whenRequired = item.getWhenRequired();
| if (whenRequired == null)
| whenRequired = ControllerState.NOT_INSTALLED;
| if (isBeforeState(dependent.getState(), whenRequired) == false)
| uninstallContext(dependent, whenRequired, trace);
| }
|
the controller (see 'this') is not scoped,
hence has no clue about scoped bean.
Dunno what kind of quick hack could fix this. :-)
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4171267#4171267
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4171267
17 years, 7 months
[Design of POJO Server] - Re: Using AnnotationEnvironment in Seam
by pete.muir@jboss.org
Here are some questions/comments:
1) We currently only scan artifacts which have seam.properties (or META-INF/seam.properties or META-INF/components.xml). This includes:
* WEB-INF/classes
* Any lib in WEB-INF/lib
* Any lib declared in the manifest
* Any lib declared in the ear (e.g. in lib/, declared as an ejb in application.xml, declared in the manifest)
* Any lib in our parent classloaders
How do we replicate this behaviour?
2) We have other deployment handlers
e.g. org.jboss.seam.deployment.ComponentsXmlDeploymentHandler::handle
public void handle(String name, ClassLoader classLoader)
| {
| if (name.endsWith(".component.xml") || name.endsWith("/components.xml"))
| {
| // we want to skip over known meta-directories since Seam will
| // auto-load these without a scan
| if (!name.startsWith("WEB-INF/") && !name.startsWith("META-INF/"))
| {
| resources.add(name);
| }
| }
|
| }
For this approach to decrease deployment time, we need to not scan at all (or scan a very limited set of files), so can we get this metadata (files, based on their filename) from the MC?
If you want to look at the handlers which are relevant:
* org.jboss.seam.deployment.AnnotationDeploymentHandler (support for users to specify their own annotations to handle, the AnnotationEnv backed version can just be a facade)
* org.jboss.seam.deployment.ComponentDeploymentHandler
* org.jboss.seam.deployment.ComponentsXmlDeploymentHandler
* org.jboss.seam.deployment.DotPageDotXmlDeploymentHandler
* org.jboss.seam.deployment.NamespaceDeploymentHandler
* org.jboss.seam.bpm.PageflowDeploymentHandler
3) For the future, can we add support for metaannotations support? This will make it supereasy to use for WB.
E.g.
public interface AnnotationEnvironment
| {
| ...
| boolean hasClassMetaAnnotatedWith(Class<? extends Annotation> annotation);
|
| // etc.
|
annotationEnvironment.hasClassMetaAnnotatedWith(javax.webbeans.DeploymentType.class);
4) How does it handle exceptions loading classes? Throw them for us to catch?
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4171248#4171248
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4171248
17 years, 7 months
[Design of POJO Server] - Using AnnotationEnvironment in Seam
by alesj
I'll describe a bit how AnnotationEnvoroment works, where it comes from, ...
but then it should be up to Seam guys to fully incorporate this into Seam's
component scanning / lookup.
AnnotationEnv API:
| public interface AnnotationEnvironment
| {
| /**
| * Does this annotation environment contain a class
| * which is annotated with annotation parameter.
| * This only applies to annotations for ElementType.TYPE level.
| *
| * This method should be used if we have no intention
| * to do real lookup of annotated classes, but we're
| * only interested in existance of the annotation.
| * e.g. deployment unit contains @Stateful EJBs
| *
| * @param annotation the annotation we're querying for
| * @return true if there exists a class with annotation param
| * @see #hasClassAnnotatedWith(Class annotation)
| */
| boolean hasClassAnnotatedWith(Class<? extends Annotation> annotation);
|
| /**
| * Does this annotation environment contain a class
| * which is annotated with annotation parameter.
| * This only applies to annotations for ElementType.TYPE level.
| *
| * This method should be used if we have no intention
| * to do real lookup of annotated classes, but we're
| * only interested in existance of the annotation.
| * e.g. deployment unit contains @Stateful EJBs
| *
| * @param annotationName the annotation name we're querying for
| * @return true if there exists a class with annotation param
| * @see #hasClassAnnotatedWith(Class annotation)
| */
| boolean hasClassAnnotatedWith(String annotationName);
|
| /**
| * Get all classes annotated with annotation param.
| *
| * @param <A> the annotation type
| * @param annotation the annotation we're querying for
| * @return set of matching classes
| */
| <A extends Annotation> Set<Element<A, Class<?>>> classIsAnnotatedWith(Class<A> annotation);
|
| /**
| * Get all classes annotated with annotation param.
| *
| * @param annotationName the annotation name we're querying for
| * @return set of matching classes
| */
| Set<Element<Annotation, Class<?>>> classIsAnnotatedWith(String annotationName);
|
| /**
| * Get all classes who have some constructor annotated with annotation param.
| *
| * @param <A> the annotation type
| * @param annotation the annotation we're querying for
| * @return set of matching classes
| */
| <A extends Annotation> Set<Element<A, Constructor<?>>> classHasConstructorAnnotatedWith(Class<A> annotation);
|
| /**
| * Get all classes who have some constructor annotated with annotation param.
| *
| * @param annotationName the annotation name we're querying for
| * @return set of matching classes
| */
| Set<Element<Annotation, Constructor<?>>> classHasConstructorAnnotatedWith(String annotationName);
|
| /**
| * Get all classes who have some field annotated with annotation param.
| *
| * @param <A> the annotation type
| * @param annotation the annotation we're querying for
| * @return set of matching classes
| */
| <A extends Annotation> Set<Element<A, Field>> classHasFieldAnnotatedWith(Class<A> annotation);
|
| /**
| * Get all classes who have some field annotated with annotation param.
| *
| * @param annotationName the annotation name we're querying for
| * @return set of matching classes
| */
| Set<Element<Annotation, Field>> classHasFieldAnnotatedWith(String annotationName);
|
| /**
| * Get all classes who have some method annotated with annotation param.
| *
| * @param <A> the annotation type
| * @param annotation the annotation we're querying for
| * @return set of matching classes
| */
| <A extends Annotation> Set<Element<A, Method>> classHasMethodAnnotatedWith(Class<A> annotation);
|
| /**
| * Get all classes who have some method annotated with annotation param.
| *
| * @param annotationName the annotation name we're querying for
| * @return set of matching classes
| */
| Set<Element<Annotation, Method>> classHasMethodAnnotatedWith(String annotationName);
|
| /**
| * Get all classes who have some method's/constructor's parameter annotated with annotation param.
| *
| * @param <A> the annotation type
| * @param annotation the annotation we're querying for
| * @return set of matching classes
| */
| <A extends Annotation> Set<Element<A, AnnotatedElement>> classHasParameterAnnotatedWith(Class<A> annotation);
|
| /**
| * Get all classes who have some method's/constructor's parameter annotated with annotation param.
| *
| * @param annotationName the annotation name we're querying for
| * @return set of matching classes
| */
| Set<Element<Annotation, AnnotatedElement>> classHasParameterAnnotatedWith(String annotationName);
| }
|
| public interface Element<A extends Annotation, M extends AnnotatedElement>
| {
| /**
| * Get the owner class name.
| *
| * Until we hit getOwner method the class should not be loaded.
| *
| * @return the owner classname
| */
| String getOwnerClassName();
|
| /**
| * Get the annotation owner class.
| *
| * @return the annotation owner class
| */
| Class<?> getOwner();
|
| /**
| * Get the annotation instance.
| *
| * @return the annotation instance
| */
| A getAnnotation();
|
| /**
| * Get the annotated element that holds the annotation.
| *
| * @return the annotated element instance
| */
| M getAnnotatedElement();
| }
|
The API is pretty simple :-),
as can be seen it has to 'flavors',
one where you put direct annotation class as parameter,
the other one where you put annotation class name.
The Element has a few useful hooks,
and its impl detail is that it's completely lazy -
it doesn't load the class or annotation until asked.
There is a flag on the annotation scanning deployer,
that allows for AnnotationEnvironment to already keep
the annotation instance gathered from Javassist lookup -
meaning you don't even need to load the class to
inspect annotation value.
e.g. you only need classname + annotation member values
When (annotation scanning) deployers are properly configured,
this is already the case in current JBoss5 trunk,
every deployment unit gets AnnotationEnvironment as an attachment.
| DeploymentUnit unit = getAttribute(context, DeploymentUnit.class.getName(), DeploymentUnit.class);
| AnnotationEnvironment env = unit.getAttachment(AnnotationEnvironment.class);
|
In the Seam case we would have to do a bit of
hierarchy traversing to get all the AnnotationEnvironments,
from all deployment units, since we only have web deployment unit,
in the ServletContext attributes.
| public class JBossSeamListener extends SeamListener
| {
| public void contextInitialized(ServletContextEvent event)
| {
| // TODO - enable some MC scanning notion in Seam
| super.contextInitialized(event);
|
| ServletContext context = event.getServletContext();
| Kernel kernel = getAttribute(context, Kernel.class.getName(), Kernel.class);
| DeploymentUnit unit = getAttribute(context, DeploymentUnit.class.getName(), DeploymentUnit.class);
|
Looking at the ComponentDeploymentHandler::handle
| public void handle(String name, ClassLoader classLoader)
| {
| if (name.endsWith(".class"))
| {
| String classname = filenameToClassname(name);
| String filename = componentFilename(name);
| try
| {
| ClassFile classFile = getClassFile(name, classLoader);
| boolean installable = ( hasAnnotation(classFile, Name.class) || classLoader.getResources(filename).hasMoreElements() )
| && !"false".equals( getAnnotationValue(classFile, Install.class, "value") );
| if (installable)
| {
| log.trace("found component class: " + name);
| classes.add( (Class<Object>) classLoader.loadClass(classname) );
| }
|
Looks like we should also do a bit more than just looking for @Name,
but for the @Install::value==false it should be just a simple Set intersection.
Where I don't see what exactly does "classLoader.getResources(filename).hasMoreElements() " do/help.
Pete & co., if you need any other info,
post it here. :-)
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4171242#4171242
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4171242
17 years, 7 months