-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
ArgumentArraySizeWithLookupTest (and related) failing against Weld 6.0.0 in GF #593
Comments
I suppose it's differences in how WFLY and GF handle bean archives.
That sounds like GF places the extension into a separate bean archive, why? |
I'll check WildFly too to be sure then. |
@arjantijms so in WFLY, I can see that the invoker is registered in a different bean archive as well, namely
While BM of the test deployment archive is something like this:
But I guess the difference in GF is the accessibility graph between deployments - in WFLY the first BM[1] always has the latter BM[2] under its list of accessible managers and can therefore "see" the dependencies and resolve them. |
@manovotn that's interesting. I did a little tracing how the
There, the private <T> void processBeanRegistration(BeanRegistration registration, GlobalEnablementBuilder globalEnablementBuilder) {
Bean<?> bean = registration.initBean();
BeanManagerImpl beanManager = registration.initBeanManager();
### beanManager = Weld BeanManager for org.jboss.arquillian.testenricher.cdi.container.CDIExtension [bean count=32]
if (beanManager == null) {
// Get the bean manager for beans added via ABD#addBean()
beanManager = getOrCreateBeanDeployment(bean.getBeanClass()).getBeanManager();
} else {
// Also validate the bean produced by a builder
### getBeanManager() = Weld BeanManager for deployment [bean count=14]
ExternalBeanAttributesFactory.validateBeanAttributes(bean, getBeanManager());
validateBean(bean);
}
// code ommitted
} else {
### beanManager = Weld BeanManager for org.jboss.arquillian.testenricher.cdi.container.CDIExtension [bean count=32]
beanManager.addBean(bean);
if (priority != null && bean.isAlternative()) {
globalEnablementBuilder.addAlternative(bean.getBeanClass(), priority);
}
}
containerLifecycleEvents.fireProcessBean(beanManager, bean, registration.extension);
} I've not yet found how "[beanDeploymentArchiveId=org-jboss.weld.bootstrap.WeldExtension]" is created from "Weld BeanManager for org.jboss.arquillian.testenricher.cdi.container.CDIExtension". If there is no
Which is typically (always?) the bean archive corresponding to the jar file the extension physically resides in. |
This one seems related too: weld/core#2909 In GlassFish, the LiteExtensionTranslator, which is also into play here, is added manually: @Override
public Iterable<Metadata<Extension>> getExtensions() {
if (extensions != null) {
return extensions;
}
List<Metadata<Extension>> extensionsList = new ArrayList<>();
// Register org.jboss.weld.lite.extension.translator.LiteExtensionTranslator in order to be able to execute build compatible extensions
// Note that we only register this if we discovered at least one implementation of BuildCompatibleExtension
List<Class<? extends BuildCompatibleExtension>> buildExtensions = getBuildCompatibleExtensions();
if (!buildExtensions.isEmpty()) {
try {
extensionsList.add(new MetadataImpl<>(new LiteExtensionTranslator(buildExtensions, Thread.currentThread().getContextClassLoader())));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
for (BeanDeploymentArchive beanDeploymentArchive : getBeanDeploymentArchives()) {
if (!(beanDeploymentArchive instanceof RootBeanDeploymentArchive)) {
ClassLoader classLoader = new FilteringClassLoader(((BeanDeploymentArchiveImpl) beanDeploymentArchive)
.getModuleClassLoaderForBDA());
extensions = context.getTransientAppMetaData(WELD_BOOTSTRAP, WeldBootstrap.class)
.loadExtensions(classLoader);
if (extensions != null) {
for (Metadata<Extension> beanDeploymentArchiveExtension : extensions) {
extensionsList.add(beanDeploymentArchiveExtension);
}
}
}
}
return extensionsList;
} I do wonder where and how to setup "org.jboss.weld.core.additionalClasses". |
No, this is purely for Weld SE where there is always a synthetic bean archive. That's not the case for EE. However, you are correct that
IIRC, that's a helper archive created in WFLY for classes coming from a non-bean archive and needing one to reside in.
Not sure I follow. |
It's hard to follow indeed. The LiteExtensionTranslator and its bean manager is used all the time, e.g. inside the InvokerFactory that the TCK extension gets to see, and in the synthesis method called from The for (SyntheticBeanBuilderImpl<?> syntheticBean : syntheticBeans) {
jakarta.enterprise.inject.spi.configurator.BeanConfigurator<Object> configurator;
if (abd instanceof AfterBeanDiscoveryImpl) {
// specify the receiver class to be the BCE extension, linking the bean to it
// in EE env this affects the BM used for dynamic resolution inside bean creation method
### extensionClass = class org.jboss.cdi.tck.tests.invokers.lookup.ArgumentArraySizeWithLookupTest$TestExtension
configurator = ((AfterBeanDiscoveryImpl) abd).addBean(syntheticBean.extensionClass);
### configurator.beanManager = the arquillean CDIExtension one |
So it seems the problem is most likely here: Weld calls ### beanClass = org.jboss.cdi.tck.tests.invokers.lookup.ArgumentArraySizeWithLookupTest$TestExtension
beanDeploymentFinder.getOrCreateBeanDeployment(beanClass).getBeanManager(); Which at some point delegates to a
@Override
public BeanDeploymentArchive loadBeanDeploymentArchive(Class<?> beanClass) {
if (LOG.isLoggable(FINE)) {
LOG.log(FINE, LOAD_BEAN_DEPLOYMENT_ARCHIVE, new Object[] { beanClass });
}
// Check if we have already created a bean archive for this bean class, and if so return it.
for (BeanDeploymentArchive beanDeploymentArchive : beanDeploymentArchives) {
if (((BeanDeploymentArchiveImpl) beanDeploymentArchive).getModuleBeanClasses().contains(beanClass.getName())) {
// Don't stuff this Bean Class into the BeanDeploymentArchive's beanClasses,
// as Weld automatically add theses classes to the BeanDeploymentArchive's bean Classes
return beanDeploymentArchive;
}
// ... code ommitted
}
ClassLoader classLoaderKey = beanClass.getClassLoader();
### classLoaderKey = org.glassfish.web.loader.WebappClassLoader
BeanDeploymentArchive extensionBeanDeploymentArchive = extensionBDAMap.get(classLoaderKey);
if (extensionBeanDeploymentArchive != null) {
return extensionBeanDeploymentArchive;
}
// If the beanDeploymentArchive was not found for the Class, create one and add it
} And then Hmmmm.... |
I was able to pass this tests (and related failures) by giving the archives access to each other as follows: // Add the new archive to all existing archives
for (BeanDeploymentArchive beanDeploymentArchive : beanDeploymentArchives) {
beanDeploymentArchive.getBeanDeploymentArchives().add(newBeanDeploymentArchive);
}
// Add the existing archives archives to the new archive
newBeanDeploymentArchive.getBeanDeploymentArchives().addAll(beanDeploymentArchives); Outside the scope of this issue, but I wonder why the server has to do so many things to integrate, and why we can't move these things to Weld and the EE APIs. |
Yes, that's pretty much what I tried to explain earlier in #593 (comment) :)
I'd say because every EE server does it their own way. For instance the CL structure in WFLY has always been slightly different due to usage of JBoss Modules. I am not sure this could be unified as that spans further than just CDI; other EE technologies or custom server extensions might need a way to integrate themselves with CDI implementation in one way or another. Since this is now resolved, I will close this issue. Feel free to reopen if you think there is more to be done. |
GlassFish 8 uses Weld 6.0.0.Beta1, and for some reason that's hard to understand several TCKs tests related to Lookups are failing.
These concern for instance ArgumentArraySizeWithLookupTest where it fails with:
After investigation it appears the
Invoker
lands in a bean archive associated with the extension that creates it, while the beans related to the arguments MyDependency1 and MyDependency2 land in a bean archive associated with the deployed application.Bean invoker:
Beans for arguments:
When "[beanDeploymentArchiveId=org-jboss.weld.bootstrap.WeldExtension]" is validated, it validates the
Invoker
. This fails since theInvoker
needsMyDependency1
, which is in "[beanDeploymentArchiveId=ArgumentArraySizeWithLookupTest731093ffe4ebf3f9125ba36f0e8234a887e35]".@manovotn @Ladicek how is this supposed to work? Why does Weld passed the TCK, but still fails on GF?
The text was updated successfully, but these errors were encountered: