Issue Details (XML | Word | Printable)

Key: GLASSFISH-19215
Type: Improvement Improvement
Status: Open Open
Priority: Critical Critical
Assignee: Sivakumar Thyagarajan
Reporter: TangYong
Votes: 0
Watchers: 4
Operations

If you were logged in you would be able to see more operations.
glassfish

Add support CDI in plain OSGi bundles

Created: 23/Oct/12 06:40 AM   Updated: 11/Dec/12 09:05 AM
Component/s: OSGi-JavaEE
Affects Version/s: future release
Fix Version/s: None

Time Tracking:
Issue & Sub-Tasks
Issue Only
Not Specified

File Attachments: 1. Zip Archive GLASSFISH-19215-patch-20121211.zip (17 kB) 11/Dec/12 09:05 AM - TangYong
2. Zip Archive GLASSFISH-19215-patch.zip (15 kB) 25/Oct/12 02:06 AM - TangYong
3. Zip Archive GLASSFISH-19215-patch_20121029.zip (34 kB) 29/Oct/12 10:17 AM - TangYong
4. Zip Archive GLASSFISH-19215-patch_20121030.zip (27 kB) 30/Oct/12 01:04 PM - TangYong
5. Zip Archive GLASSFISH-19215-patch_20121109.zip (27 kB) 09/Nov/12 05:44 AM - TangYong
6. Zip Archive GLASSFISH-19215-patch_20121114.zip (29 kB) 14/Nov/12 12:23 PM - TangYong
7. Zip Archive GLASSFISH-19215_fighterfishtestcase_final_20121122.zip (54 kB) 22/Nov/12 02:27 PM - TangYong
8. Microsoft Excel reviewing_siva.xls (26 kB) 05/Dec/12 12:07 PM - TangYong
9. Microsoft Excel reviewing_siva_2012.12.10.xls (27 kB) 10/Dec/12 12:36 PM - TangYong
10. Microsoft Excel reviewing_siva_2012.12.11.xls (27 kB) 11/Dec/12 08:19 AM - TangYong
11. Zip Archive stockquote-cdi-osgi-sample.zip (58 kB) 29/Oct/12 12:18 PM - TangYong
12. Zip Archive stockquote_cdi_plainclient.zip (11 kB) 05/Nov/12 09:10 AM - TangYong


Tags:
Participants: Sanjeeb Sahoo, Sivakumar Thyagarajan and TangYong

  • Sub-Tasks:
  • All
  • Open

 Description  « Hide

In order to implement RFC146(OSGi/CDI), there is prerequisite needed to be implemented.

If a plain vanilla osgi bundle included META-INF\beans.xml and wants to use @Publish and other OSGi/CDI annotation, on current glassfish, this is not supported.

The reason is that while deploying such a osgi bundle, because missing Weld Sniffer, OSGiServiceExtension can not be triggered by WELD Container.

So, this must be implemented.



TangYong added a comment - 23/Oct/12 07:12 AM

My analyse result is that once deploying such a bundle using --type=osgi, while executing com.sun.enterprise.v3.server.SnifferManagerImpl.getApplicableSniffers method to get applicable sniffers, because archiveType is "osgi" , weld sniffer does not supports such a archiveType, weld sniffer was skipped.

I think that fixing way is that making weld sniffer can support such a case by checking beans.xml.


Sanjeeb Sahoo added a comment - 23/Oct/12 07:20 AM

No sniffer should pick up an archive when --type osgi is used. The system is designed such that only OSGiContainer will be responsible for deploying such an archive. Once such a bundle is deployed as a vanilla OSGi bundle, it should be picked up by an appropriate extender. This is how OSGi/Web, OSGi/EJB features are implemented and it should be no different for OSGi/CDI as well.


TangYong added a comment - 23/Oct/12 09:42 AM

Thanks sahoo's comment. Surely, for WAB and EJB bundle's deployment including beans.xml, real deployment is processed by OSGiWebDeployer and OSGiEJBDeployer respectively which are selected by OSGiContainer's OSGiDeployerTracker.

Then, while deploying process entered into ApplicationLifecycle, because of some magic handling(by setupClassLoader()?), getSniffers(handler, sniffers, context) can get WeldSniffer.

Backing to the problem, current deploying mode is a vanilla OSGi bundle which wants to be handled by WeldSniffer.

Just as sahoo said, it should be no different by creating a PlainOSGiDeployer. However, I have been not still clear for "some magic handling" and will continue to investigate.


TangYong added a comment - 23/Oct/12 09:56 AM

Hi sahoo,

About the "some magic handling", I have found a place and for ejb bundle, OSGiEJBDeploymentContext has a method called getArchiveType() and returned the following:

return javax.enterprise.deploy.shared.ModuleType.EJB.toString();

Then, I have seen the WeldSniffer.supportsArchiveType method and found the following:

if (archiveType.toString().equals(ModuleType.WAR.toString()) ||
archiveType.toString().equals(ModuleType.EJB.toString()) ||
archiveType.toString().equals(ModuleType.RAR.toString())) { return true; }

So, for a vanilla OSGi bundle, it is not ejb and war and rar, so, if not modifying supportsArchiveType to add the supporting of a vanilla OSGi bundle, even if creating a PlainOSGiDeployer, WeldSniffer can be not still obtained.


TangYong added a comment - 23/Oct/12 10:04 AM

For WAB, OSGiWebDeploymentContext returns the following:

@Override
public String getArchiveType() { // Since I am not able to reference GF 4.0 APIs as they are not yet staged in a maven repo, // I am accessing the value in a round about way. return javax.enterprise.deploy.shared.ModuleType.WAR.toString(); // WarType.ARCHIVE_TYPE; }

So, WAR is also supported by WeldSniffer.


TangYong added a comment - 23/Oct/12 11:39 AM

In addition, there is a thing that I must say:

For a WAB or EJB Bundle, while deploying it using --type=osgi, ApplicationLifecycle.deploy method will be called twice and "sniffers = getSniffers(handler, sniffers, context)" will also be executed twice because on the second time, OSGiContainer's OSGiDeployerTracker will select right deployer to finish javaee related things.

Then, I have made a experiment by directly modifying WeldSniffer.supportsArchiveType(archiveType.toString().equals("osgi")) so that I want to see whether a plain osgi bundle with beans.xml can be scaned by OSGiServiceExtension.

The result is that, although beans.xml can be scaned by OSGiServiceExtension, the bean class with @Publish in the plain osgi bundle can not be recognized by weld container.

So, based this conclusion,

1) WeldSniffer still needs to be enhanced
2) maybe create a new module/container(for example, osgi-cdi-se-container) to do liking osgi-ejb-container under fighterfish sub-project.


Sanjeeb Sahoo added a comment - 23/Oct/12 05:31 PM

Yes, I call it two-phase deployment. First phase involves osgi-container alone. It's the second phase where our Java EE specific extenders come into play their roles. I would expect new code to be part of osgi-cdi module itself.


TangYong added a comment - 25/Oct/12 02:06 AM

Hi sahoo, siva,

The attachement is my fixing patch and I will explain sources in the patch in details:

1 osgi-cdi

1) Similar to osgi-ejb-container, the following java files are created to meet the second phrase deployment which will trigger Weld container's bootstrap

・OSGiCDIContainerActivator.java
used to register OSGiCDIExtender class

・OSGiCDIExtender.java
An extender that registers a OSGiCDIDeployer to deploy/undeploy a plain vanilla OSGi/CDI bundle

・OSGiCDIDeployer.java
On one hand, it is used to create OSGiCDIDeploymentRequest, on the other hand, it defined a method called isPlainOSGiCDIBundle used by handles method. The isPlainOSGiCDIBundle method is very important because by means of the method, OSGiContainer can select right OSGiCDIDeployer. Please see my comments on the method and in the future, I maybe will improve the method.

・OSGiCDIDeploymentRequest.java
A simple class extends OSGiDeploymentRequest and we must add the class in order to meet osgi-javaee-base design.

・OSGiCDIUndeploymentRequest.java
A simple class extends OSGiUndeploymentRequest and we must add the class in order to meet osgi-javaee-base design.

・Constants.java
A simple class used to define some constants to avoid magic string in sources

・OSGiCDIDeploymentContext.java
It is a very important class and specially returns a new ArchiveType(javax.enterprise.deploy.shared.ModuleType.PlainOSGiCDIBundle) used by WeldSniffer.

Defaultly, OSGiArchiveHandler's getArchiveType method returned "OSGiBundle", if directly making WeldSniffer to support "OSGiBundle" type and not adding the new type, for a plain osgi bundle without beans.xml, WeldSniffer will be also added, so, I created a new type to
differentiate a plain osgi bundle without beans.xml.

2)osgi.bundle.patch
Add Bundle-Activator: org.glassfish.osgicdi.impl.OSGiCDIContainerActivator

3)pom.xml.patch
Add the following dependency,
<dependency>
<groupId>org.glassfish.main</groupId>
<artifactId>javax.enterprise.deploy</artifactId>
<version>4.0-SNAPSHOT</version>
</dependency>

Pl. seeing my comments on the the file.

2 javax.enterprise.deploy
I added a new PlainOSGiCDIBundle Module Type used by WeldSniffer.

3 gf-weld-connector
WeldSniffer's supportsArchiveType method is modified to add the supporting of PlainOSGiCDIBundle Module Type.

4 osgi-container
PlainOSGiCDIArchiveType class needs to be created as a service of ArchiveType @Contract, if not creating the class, SnifferManagerImpl's getApplicableSniffers method can not add WeldSniffer successfully.

Please review these files.


Sanjeeb Sahoo added a comment - 25/Oct/12 07:03 AM

From an initial look, they all look fine except the addition of a new module type and its use inside WeldSniffer. I think we should avoid using WeldSniffer. We should invoke Weld directly during deployment. I will let Siva comment on this.


TangYong added a comment - 26/Oct/12 02:40 AM - edited

>We should invoke Weld directly during deployment.
Indeed, invoking Weld directly is a good idea because I have found that using WeldSniffer is not a right solution because once using WeldSniffer, on the second phrase, deployment will trigger a org.glassfish.internal.deployment.Deployment.APPLICATION_LOADED event which will be listened by org.glassfish.weld.WeldDeployer, then WeldDeploy will start Weld Container. This looks very fine, but current gf weld integration only considers JavaEE related mode[1], rathen than pure OSGi or SE mode.

So, if invoking Weld directly on deploying, we should do the following-liking in order:

(1) WeldBootstrap bootstrap = new WeldBootstrap();
(2) DeploymentImpl deploymentImpl = new DeploymentImpl(archive, ejbs, deploymentContext);
(3) List<BeanDeploymentArchive> archives = deploymentImpl.getBeanDeploymentArchives();
(4) deploymentImpl.buildDeploymentGraph();
(5) bootstrap.startContainer(Environments.SE, deploymentImpl);
(6) bootstrap.startInitialization();
(7) fireProcessInjectionTargetEvents(bootstrap, deploymentImpl);
(8) bootstrap.deployBeans();

Let us see the above sequence:

1. about DeploymentImpl and BeanDeploymentArchive
I have not still made sure whether the two essential classes can be used in pure OSGi or SE mode because most of them are related to JavaEE.

2 about bootstrap.startContainer(Environments.SE, deploymentImpl);
Whether 1st Parameter is Environments.SE or others(including we create a implementation of Enviroment. Note: Weld-OSGi creates a implementation of Enviroment) or not needs to be investigated.

3 about fireProcessInjectionTargetEvents(bootstrap, deploymentImpl);
Whether needing the call or not needs to be investigated.

I will listen to Siva and Sahoo's comments.

[1]: I have found a exception on using WeldSniffer, and made sure that using WeldSniffer is not a good solution.

[#|2012-10-25T15:15:16.671+0900|WARNING|44.0|javax.enterprise.system.core.org.glassfish.kernel.event|_ThreadID=13;_ThreadName=pool-17-thread-1;_TimeMillis=1351145716671;_LevelValue=900;|Exception while dispatching an event
java.lang.RuntimeException: Error binding app-level env dependencies null
at com.sun.enterprise.container.common.impl.managedbean.ManagedBeanManagerImpl.registerAppLevelDependencies(ManagedBeanManagerImpl.java:176)
at com.sun.enterprise.container.common.impl.managedbean.ManagedBeanManagerImpl.event(ManagedBeanManagerImpl.java:136)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128)
at org.glassfish.internal.data.ApplicationInfo.load(ApplicationInfo.java:275)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:502)
at com.sun.enterprise.v3.server.ApplicationLifecycle.deploy(ApplicationLifecycle.java:228)
at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.deploy(OSGiDeploymentRequest.java:183)
at org.glassfish.osgijavaeebase.OSGiDeploymentRequest.execute(OSGiDeploymentRequest.java:118)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.deploy(AbstractOSGiDeployer.java:123)
at org.glassfish.osgijavaeebase.OSGiContainer.deploy(OSGiContainer.java:154)
at org.glassfish.osgijavaeebase.JavaEEExtender.deploy(JavaEEExtender.java:109)
at org.glassfish.osgijavaeebase.JavaEEExtender.access$200(JavaEEExtender.java:61)
at org.glassfish.osgijavaeebase.JavaEEExtender$HybridBundleTrackerCustomizer$1.call(JavaEEExtender.java:153)
at org.glassfish.osgijavaeebase.JavaEEExtender$HybridBundleTrackerCustomizer$1.call(JavaEEExtender.java:150)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.naming.NamingException: Null appName
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.getAppNamespace(GlassfishNamingManagerImpl.java:432)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.bindToAppNamespace(GlassfishNamingManagerImpl.java:595)
at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl.bindToComponentNamespace(ComponentEnvManagerImpl.java:208)
at com.sun.enterprise.container.common.impl.managedbean.ManagedBeanManagerImpl.registerAppLevelDependencies(ManagedBeanManagerImpl.java:174)
... 18 more


TangYong added a comment - 26/Oct/12 02:58 AM

The improvement is very critical to implement the whole RFC146(OSGi/CDI) and I will postpone other OSGi/CDI features's implementation until the problem is resolved.

In addition, remembering siva's "Typesafe injection of dynamic OSGi services in hybrid Java EE applications"(https://blogs.oracle.com/sivakumart/entry/typesafe_injection_of_dynamic_osgi) , the sample used a servlet consumer,

public class StockQuoteServlet extends HttpServlet { @Inject @OSGiService(/\* wait for 1 min \*/ waitTimeout=60\*1000) StockQuoteService sqs; ... }

Servlet consumer is one of of consumers of OSGi/CDI @OSGiService, and plain OSGi bundle should be also another use case, if the improvement can not be resolved, @OSGiService can not be used in plain OSGi bundle's use case,let alone say @Publish ...


Sivakumar Thyagarajan added a comment - 26/Oct/12 11:36 AM

Hi Tang

I agree with Sahoo and you that we should not use WeldSniffer. It unnecessarily ties the osgi-cdi implementation to the weld-integration module in GlassFish. We should see the work you are doing in OSGi-CDI as only meant to support OSGi bundles as CDI bean archives, and leave the support for Java EE CDI bean archives to the Weld integration. Directly using the Weld SPI to do deployment of bean archives is the right approach.

> 1. about DeploymentImpl and BeanDeploymentArchive
> I have not still made sure whether the two essential classes can be used in pure OSGi or SE mode
> because most of them are related to JavaEE.

Yes, these SPI implementations in the weld-integration module is very EE specific and may not be useful as is to you. Could you please look at implementing light-weight implementations of these to just support the "OSGi bundles as bean archives" scenario.

> 2 about bootstrap.startContainer(Environments.SE, deploymentImpl);
> Whether 1st Parameter is Environments.SE or others(including we create a implementation of
> Enviroment. Note: Weld-OSGi creates a implementation of Enviroment) or not needs to be
> investigated.

For now let us assume that the support for "OSGi bundles as bean archives" is just an SE style environment as we don't need to support EE style resource injection, transactions, Servlet, EJB etc. So let us start with reusing Environments.SE.

Firing ProcessInjectionTarget events was done in DeploymentImpl for handling non-contextual EE components such as Services. In this case, this may not be needed.

Thanks.


TangYong added a comment - 28/Oct/12 06:52 AM - edited

Thanks siva's confirmation and sahoo's change on the improvement's title.

>Yes, these SPI implementations in the weld-integration module is very EE specific and may not be useful as is to
>you. Could you please look at implementing light-weight implementations of these to just support the "OSGi bundles >as bean archives" scenario.
I am investigating this.

>For now let us assume that the support for "OSGi bundles as bean archives" is just an SE style environment as we >don't need to support EE style resource injection, transactions, Servlet, EJB etc. So let us start with reusing >Environments.SE.
On Weld-OSGi project and ops4j.pax.cdi project, they all create a new environment used for OSGi/CDI rather than using Environments.SE, so, I must investigate the reason that they do not use Environments.SE directly.

>Firing ProcessInjectionTarget events was done in DeploymentImpl for handling non-contextual EE components such as >Services. In this case, this may not be needed.
OK, I see.

In addition, I will add a topic as following:

Needing to investigate that ,by overriding which method, directly using the Weld SPI is to do deployment of bean archives.


TangYong added a comment - 29/Oct/12 10:17 AM

Hi siva, sahoo,

I have implemented the improvement and have made a @Publish test(based my current @Publish implementation). Please review the patch(20121029). I want to make a description about essential classes of the patch.

1) OSGiBeanDeploymentArchiveImpl
>Yes, these SPI implementations in the weld-integration module is very EE specific and may >not be useful as is to you. Could you please look at implementing light-weight >implementations of these to just support the "OSGi bundles as bean archives" scenario.

the class is a OSGi bundles bean archives's implementation

2) OSGiBeanDeploymentArchiveFactory
its role is scanning current bundle and finding beans.xml and bean classes used by weld

3) OSGiBeanDeployment
used by WeldBootstrap to start weld container

4) OSGiCDIDeploymentRequest
>Needing to investigate that ,by overriding which method, directly using the Weld SPI is >to do deployment of bean archives.

Overriding postDeploy() method to trigger Weld SPI directly.

5) OSGiServicePublisher and Publish and ServiceProperties and Property
handling @Publish and registering current Bean into OSGi, I will discuss @Publish in Glassfish-18938

6) about Environments.SE
Currently, using Environments.SE looks fine.

Thanks


TangYong added a comment - 29/Oct/12 12:14 PM

Hi sahoo,siva

On testing the improvement based my patch, I found two problem on stopping domain:

1) osgi-ejb-container

After I deployed a plain bundle with beans.xml, while I was executing "asadmin stop-domain", the following exception happened on server.log,

[#|2012-10-29T18:57:24.843+0900|SEVERE|44.0|javax.enterprise.logging.stderr|_ThreadID=14;_ThreadName=Thread-16;_TimeMillis=1351504644843;_LevelValue=1000;|java.lang.NullPointerException
at org.glassfish.osgiejb.OSGiEJBDeployer$EJBTracker.removedService(OSGiEJBDeployer.java:236)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:1006)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:906)
at org.osgi.util.tracker.AbstractTracked.untrack(AbstractTracked.java:352)
at org.osgi.util.tracker.ServiceTracker$Tracked.serviceChanged(ServiceTracker.java:949)
at org.apache.felix.framework.util.EventDispatcher.invokeServiceListenerCallback(EventDispatcher.java:932)
at org.apache.felix.framework.util.EventDispatcher.fireEventImmediately(EventDispatcher.java:793)
at org.apache.felix.framework.util.EventDispatcher.fireServiceEvent(EventDispatcher.java:543)
at org.apache.felix.framework.Felix.fireServiceEvent(Felix.java:4260)
at org.apache.felix.framework.Felix.access$000(Felix.java:74)
at org.apache.felix.framework.Felix$1.serviceChanged(Felix.java:390)
at org.apache.felix.framework.ServiceRegistry.unregisterService(ServiceRegistry.java:148)
at org.apache.felix.framework.ServiceRegistrationImpl.unregister(ServiceRegistrationImpl.java:127)
at org.glassfish.osgijavaeebase.OSGiContainer.undeploy(OSGiContainer.java:184)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.undeployAll(AbstractOSGiDeployer.java:168)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.unregister(AbstractOSGiDeployer.java:115)
at org.glassfish.osgicdi.impl.OSGiCDIExtender.stop(OSGiCDIExtender.java:72)
at org.glassfish.osgijavaeebase.ExtenderManager$ExtenderTracker.removedService(ExtenderManager.java:153)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:1006)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:906)
at org.osgi.util.tracker.AbstractTracked.untrack(AbstractTracked.java:352)
at org.osgi.util.tracker.ServiceTracker.close(ServiceTracker.java:412)
at org.glassfish.osgijavaeebase.ExtenderManager.stopExtenders(ExtenderManager.java:122)
at org.glassfish.osgijavaeebase.ExtenderManager.access$400(ExtenderManager.java:67)
at org.glassfish.osgijavaeebase.ExtenderManager$GlassFishServerTracker$1$1.event(ExtenderManager.java:197)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128)
at com.sun.enterprise.v3.server.AppServerStartup.stop(AppServerStartup.java:324)
at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.stop(GlassFishImpl.java:88)
at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.stop(GlassFishDecorator.java:68)
at com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishImpl.stop(EmbeddedOSGiGlassFishImpl.java:80)
at com.sun.enterprise.v3.admin.StopServer.doExecute(StopServer.java:78)
at com.sun.enterprise.v3.admin.StopDomainCommand.execute(StopDomainCommand.java:95)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:549)
at org.glassfish.api.AsyncImpl$1$1.run(AsyncImpl.java:79)

#]

I analysed for a while and made a modification for EJBTracker.removedService method 236 line as following,

Application app = ai.getMetaData(Application.class);
if (app != null ){ Collection<DolAdapter.EjbDescriptor> ejbs = DolAdapter.convert(app.getEjbDescriptors()); ... }
super.removedService(reference, service);

I found that while deploying a plain bundle with beans.xml, ApplicationInfo of the bundle has no metadata, so, NullPointerException happened. However, I also doubted whether the exception was caused by my patch or not?

2)AbstractOSGiDeployer.getGlassFish

After I made the above modification, the 1) exception did not happen, however, another exception happened on the server.log,

[#|2012-10-29T18:57:24.843+0900|WARNING|44.0|org.glassfish.osgijavaeebase|_ThreadID=14;_ThreadName=Thread-16;_TimeMillis=1351504644843;_LevelValue=900;|Failed to undeploy bundle sample.osgicdi.stockquote_service_usingcdi [280]
java.lang.NullPointerException: Specified service reference cannot be null.
at org.apache.felix.framework.BundleContextImpl.getService(BundleContextImpl.java:458)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.getGlassFish(AbstractOSGiDeployer.java:197)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.getReport(AbstractOSGiDeployer.java:149)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.undeploy(AbstractOSGiDeployer.java:137)
at org.glassfish.osgijavaeebase.OSGiContainer.undeploy(OSGiContainer.java:193)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.undeployAll(AbstractOSGiDeployer.java:168)
at org.glassfish.osgijavaeebase.AbstractOSGiDeployer.unregister(AbstractOSGiDeployer.java:115)
at org.glassfish.osgicdi.impl.OSGiCDIExtender.stop(OSGiCDIExtender.java:72)
at org.glassfish.osgijavaeebase.ExtenderManager$ExtenderTracker.removedService(ExtenderManager.java:153)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:1006)
at org.osgi.util.tracker.ServiceTracker$Tracked.customizerRemoved(ServiceTracker.java:906)
at org.osgi.util.tracker.AbstractTracked.untrack(AbstractTracked.java:352)
at org.osgi.util.tracker.ServiceTracker.close(ServiceTracker.java:412)
at org.glassfish.osgijavaeebase.ExtenderManager.stopExtenders(ExtenderManager.java:122)
at org.glassfish.osgijavaeebase.ExtenderManager.access$400(ExtenderManager.java:67)
at org.glassfish.osgijavaeebase.ExtenderManager$GlassFishServerTracker$1$1.event(ExtenderManager.java:197)
at org.glassfish.kernel.event.EventsImpl.send(EventsImpl.java:128)
at com.sun.enterprise.v3.server.AppServerStartup.stop(AppServerStartup.java:324)
at com.sun.enterprise.glassfish.bootstrap.GlassFishImpl.stop(GlassFishImpl.java:88)
at com.sun.enterprise.glassfish.bootstrap.GlassFishDecorator.stop(GlassFishDecorator.java:68)
at com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishImpl.stop(EmbeddedOSGiGlassFishImpl.java:80)
at com.sun.enterprise.v3.admin.StopServer.doExecute(StopServer.java:78)
at com.sun.enterprise.v3.admin.StopDomainCommand.execute(StopDomainCommand.java:95)
at com.sun.enterprise.v3.admin.CommandRunnerImpl$2.execute(CommandRunnerImpl.java:549)
at org.glassfish.api.AsyncImpl$1$1.run(AsyncImpl.java:79)

#]

While I was debugging the exception, the exception happened on AbstractOSGiDeployer.getGlassFish() method 197,
"getBundleContext().getServiceReference(GlassFish.class.getName())" is null, however, I felt very curious,

・Whether on EJB Bundle case or WAB case the exception also happened or not?
・From exception, It seemed that it should be not related to my patch.

I want to listen your comments.
Thanks.


TangYong added a comment - 29/Oct/12 12:18 PM

I attached my test application and I used stockquote_service_usingcdi as deploying sample.


Sanjeeb Sahoo added a comment - 29/Oct/12 05:38 PM

Tang,

1. I agree with your assessment of first exception. We may have to adopt a different strategy for OSGi/CDI instead of implementing them like OSGi/EJB or OSGi/Web. Can you please explore if we can just have an extender which registers a BundleTracker that does what you are doing in OSGiCDIDeploymentRequest?

2. The second exception sounds like a bug to me. Since GlassFish service is getting removed, it is likely that getBundleContext().getServiceReference(GlassFish.class.getName()) is returning null. Can you please try to reproduce it for an EJB bundle or WAB and file a bug?

Very good work, BTW.

Thanks,
Sahoo


TangYong added a comment - 30/Oct/12 01:38 AM

Hi sahoo,

For 1, I will investigate it and at the same time I will also listen to siva's comments for other sources of my patch.

For 2, I will try EJB bundle and WAB and see whether the exception will happen again or not?

Thanks your suggestion.
Tang


TangYong added a comment - 30/Oct/12 11:03 AM

Hi sahoo,

>For 2, I will try EJB bundle and WAB and see whether the exception will happen again or not?
I have confirmed that 2 can be reproduced and please see GLASSFISH-19261 .


TangYong added a comment - 30/Oct/12 01:04 PM

Hi sahoo, siva,

I have attached my new patch according to sahoo's comment and I can deploy stockquote_service_usingcdi.jar successfully, In the patch, modified class is OSGiCDIExtender, and I add BeanBundleTrackerCustomizer to track deployed bundle, once finding the bundle is a plain bundle with beans.xml, I trigger Weld SPI directly.

In addition, after executing stop-domain, previous 1 and 2 exceptions all disappeared in server.log. The following is server.log's contents in my env. Currently, it looks fine.

[#|2012-10-30T21:54:08.531+0900|INFO|44.0|null|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601648531;_LevelValue=800;|Snifer org.glassfish.extras.osgicontainer.OSGiSniffer@343329 set up following modules: []|#]

[#|2012-10-30T21:54:08.921+0900|INFO|44.0|javax.enterprise.logging.stdout|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601648921;_LevelValue=800;|Started sample.osgicdi.stockquote_service_usingcdi [280]|#]

[#|2012-10-30T21:54:08.937+0900|INFO|44.0|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601648937;_LevelValue=800;_MessageID=loading.application.time;|CORE10010: Loading application stockquote_service_usingcdi done in 594 ms|#]

[#|2012-10-30T21:54:08.968+0900|INFO|44.0|org.glassfish.ha.store.spi.BackingStoreFactoryRegistry|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601648968;_LevelValue=800;|Registered org.glassfish.ha.store.adapter.cache.ShoalBackingStoreProxy for persistence-type = replicated in BackingStoreFactoryRegistry|#]

[#|2012-10-30T21:54:08.968+0900|INFO|44.0|javax.enterprise.system.core.com.sun.enterprise.v3.server|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601648968;_LevelValue=800;|GlassFish Server Open Source Edition 4.0 (Administrator-private) startup time : Felix (2,641ms), startup services(1,859ms), total(4,500ms)|#]

[#|2012-10-30T21:54:09.031+0900|INFO|44.0|javax.enterprise.system.core.com.sun.enterprise.v3.services.impl|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601649031;_LevelValue=800;|Grizzly Framework 2.3 started in: 16ms - bound to [/0.0.0.0:7,676]|#]

[#|2012-10-30T21:54:09.109+0900|INFO|44.0|javax.enterprise.system.jmx|_ThreadID=11;_ThreadName=Thread-7;_TimeMillis=1351601649109;_LevelValue=800;_MessageID=AS-JMX-00005;|JMXStartupService has started JMXConnector on JMXService URL service:jmx:rmi://10.167.157.133:8686/jndi/rmi://10.167.157.133:8686/jmxrmi|#]

[#|2012-10-30T21:54:09.171+0900|INFO|44.0|com.sun.enterprise.glassfish.bootstrap.osgi|_ThreadID=10;_ThreadName=main;_TimeMillis=1351601649171;_LevelValue=800;|Registered com.sun.enterprise.glassfish.bootstrap.osgi.EmbeddedOSGiGlassFishImpl@1869971 as OSGi service registration: org.apache.felix.framework.ServiceRegistrationImpl@432685|#]

[#|2012-10-30T21:54:09.531+0900|INFO|44.0|org.jboss.weld.Version|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649531;_LevelValue=800;|WELD-000900 1.1.4 (Final)|#]

[#|2012-10-30T21:54:09.781+0900|INFO|44.0|org.jboss.weld.Bootstrap|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649781;_LevelValue=800;|WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.|#]

[#|2012-10-30T21:54:09.921+0900|WARNING|44.0|org.jboss.interceptor.util.InterceptionTypeRegistry|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649921;_LevelValue=900;|Class 'javax.interceptor.AroundInvoke' not found, interception based on it is not enabled|#]

[#|2012-10-30T21:54:09.921+0900|WARNING|44.0|org.jboss.interceptor.util.InterceptionTypeRegistry|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649921;_LevelValue=900;|Class 'javax.interceptor.AroundTimeout' not found, interception based on it is not enabled|#]

[#|2012-10-30T21:54:09.921+0900|WARNING|44.0|org.jboss.interceptor.util.InterceptionTypeRegistry|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649921;_LevelValue=900;|Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled|#]

[#|2012-10-30T21:54:09.937+0900|WARNING|44.0|org.jboss.interceptor.util.InterceptionTypeRegistry|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649937;_LevelValue=900;|Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled|#]

[#|2012-10-30T21:54:09.937+0900|INFO|44.0|javax.enterprise.logging.stdout|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649937;_LevelValue=800;|SimpleStockQuoteServiceImplUsingCDI::Initializing quotes|#]

[#|2012-10-30T21:54:09.937+0900|INFO|44.0|javax.enterprise.logging.stdout|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649937;_LevelValue=800;|SimpleStockQuoteServiceImplUsingCDI::getSymbols|#]

[#|2012-10-30T21:54:09.937+0900|INFO|44.0|javax.enterprise.logging.stdout|_ThreadID=12;_ThreadName=pool-6-thread-1;_TimeMillis=1351601649937;_LevelValue=800;|Registered:[IBM, Fujitsu, HPQ, ORCL]|#]

Please Sahoo and Siva review.


TangYong added a comment - 30/Oct/12 01:34 PM

I made a improvement for BeanBundleTrackerCustomizer.addingBundle method,

public Object addingBundle(final Bundle bundle, BundleEvent event) {
if ( !isCDIBundle(bundle) ){ return null; }

final int state = bundle.getState();

if ( isReady(event, state) ) { ... }


TangYong added a comment - 05/Nov/12 09:09 AM

There is a problem happened on my test app(Pl. seeing stockquote_cdi_plainclient.zip).

Test Case:

In activator of a plain osgi bundle, I add the following test logic,

public class OSGiPlainClientActivator implements BundleActivator{

@Inject
@OSGiService(/* dynamically bound */ dynamic = true,
/* wait for 1 min */ waitTimeout=1*1000)
StockQuoteService sqs;

public void start(BundleContext arg0) throws Exception { System.out.println("OSGiPlainClientActivator::start"); System.out.println("Obtained StockQuotes:" + sqs.getSymbols()); System.out.println("OSGiPlainClientActivator::getting Stock quote service successful"); }

On debugging, I found that sqs is NULL because before sqs is injected, Starting logic of the activator has ended.
So, here has a multi-thread problem and weld container's scanning must happen before the activator's start method.

I will investigate how to fix the problem and also listen to your comments.

The problem is very fatal.

Thanks
Tang


TangYong added a comment - 05/Nov/12 09:25 AM

I forgot to say that while deploying the test bundle, when executing BeanBundleTrackerCustomizer.isReady method, current bundle's state is Starting, the method can not return true on this case, so, I modify the method as following,

private boolean isReady(BundleEvent event, int state) { return state == Bundle.ACTIVE || state == Bundle.STARTING; }

However,Modifying the method can not fix the problem, because main reason is multi-thread which I said in previous reply.


TangYong added a comment - 05/Nov/12 09:38 AM

Hi siva, sahoo,

I made an experiment on WAB with beans.xml. I added a activator and @OSGiService on the activator's start method, the same problem happened. So, regardless of JAVAEE bundle or Plain OSGi bundle, the problem all happened.


TangYong added a comment - 05/Nov/12 09:52 AM

I think that the problem is difficult to fix because if a user used OSGi Shell command to stop the test sample and start the sample again, then, on such a case, if using listener or tracker, because they are asynchronous, injection on activator's start method can be still null.


TangYong added a comment - 05/Nov/12 10:07 AM

I have a fix way and use SynchronousBundleListener, I will try it.


TangYong added a comment - 05/Nov/12 11:16 AM - edited

In addition, because glassfish has updated Weld into 1.1.10.Final, I need to update some modified files.
Now, SynchronousBundleListener is a valid fixing solution, however, from testing, I have found another problem(Although abd.addBean(new OSGiServiceBean(svcInjectionPoint)) can be executed successfully, on injection point, sqs has been not injected a bean) and will resolve it, maybe my source has a problem related to classloader.


Sanjeeb Sahoo added a comment - 05/Nov/12 05:50 PM

Tang,

It is perfectly understandable to get an NPE when a bundle activator tries to access an injected field. It happens for two reasons:
a) The bundle activator instance is likely to be not known to the injection manager,
b) The injection happens after a bundle is activated.

So, we should treat it as a user application error.

We should demonstrate the integration using some sort of service tracker as you have mentioned.

Thanks,
Sahoo


TangYong added a comment - 06/Nov/12 07:00 AM

Hi sahoo,siva,

This problem is a litter complex and I want to make a detailed explanation.Firstly, let us see OSGi/CDI's using scene and injection process.

[OSGi/CDI's Using Scene and Injection process]
1 JavaEE Bundle's Injection
Taking a WAB as example, normally @OSGiService injection happens on a servlet as the following,

public class StockQuoteServlet extends HttpServlet { @Inject @OSGiService(dynamic = true, waitTimeout=1*1000) StockQuoteService sqs; ... }

in this case, while deploying the WAB, Weld SPI will be triggered and in "AfterBeanDiscovery" of Bean Deployment LifeCycle, a OSGiServiceBean for sqs injectionPoint will be created and added into Weld Bean Manager. Then, while a user accessed the StockQuoteServlet by browser, true injection started and the injection is triggered by WebContainer.

That is to say, in order to obtain a injected bean, there are two critical steps:
1) scanning injectionPoint and adding OSGiServiceBean
2) needing a medium or container to trigger injection

2 Plain Bundle's Injection
Taking my test sample(stockquote_cdi_plainclient.zip) as example, here I used the following test logic on a activator.

public class OSGiPlainClientActivator implements BundleActivator{

@Inject
@OSGiService(dynamic = false, waitTimeout=1*1000)
StockQuoteService sqs;

public void start(BundleContext arg0) throws Exception { System.out.println("Obtained StockQuotes:" + sqs.getSymbols()); }

Firstly, I want to express my comments on sahoo's saying "So, we should treat it as a user application error."
I think that BundleActivator is similar to "main" function in java se world, when a StockQuoteService has been available, a user is likely to use the StockQuoteService eagerly. However, just as sahoo's saying, putting @OSGiService into OSGiPlainClientActivator can not finish 2) of two critical steps because the activator has missing the chance of triggering true injection. The result is that you maybe only use OSGi related API to get StockQuoteService. This is true?

After I evaluated Weld-OSGi's a standalone example, I found that Weld-OSGi used a interesting using way to resolve the problem rather than using OSGi related API, please seeing the following.

public class StandaloneActivator implements BundleActivator {

private EmbeddedContainer embedded;
private EmbeddedCDIContainer container;
private MyService service;

@Override
public void start(BundleContext context) throws Exception { embedded = new EmbeddedContainer(context); container = embedded.initialize(); service = container.getInstance().select(MyService.class).get(); System.out.println(service.hello()); System.out.println(service.admin()); System.out.println(service.adminAvailable()); }
...
}

public class MyService { @Inject @OSGiService private PackageAdmin admin; ... }

In the StandaloneActivator's start method, MyService can be obtained by using Weld's Instance<Object> way. In order to make effect, you must use a medium(Weld-OSGi uses EmbeddedContainer) to trigger Weld SPI and save Bean Manager, then by this Bean Manager, you can obtain Instance<Object>.

However, for Glassfish, if we also offer such a medium, we must make a classification, and once a user uses the medium to trigger Weld SPI directly, because on gf's deploying phrase , Weld SPI will be also triggered, that is to say, there are two places which will trigger Weld SPI. For the problem, Weld-OSGi used a trick that if the bundle's meta-data includes "Embedded-CDIContainer: =true", Weld SPI will be only triggered in the bundle's activator, otherwise, Weld SPI will be triggered by Weld-OSGi related bundles.

I wish that I can express more clear, and maybe we will create another feature for stating the problem.

Thanks
Tang


TangYong added a comment - 06/Nov/12 07:28 AM

>However, for Glassfish, if we also offer such a medium, we must make a classification, and once a user uses the >medium to trigger Weld SPI directly, because on gf's deploying phrase , Weld SPI will be also triggered, that is to
Maybe there is another way other than using a medium to resolve the problem, and we maybe use Event integration. For example, for OSGiPlainClientActivator, the user can write the following,

public class OSGiPlainClientActivator implements BundleActivator{

private StockQuoteService sqs;

public void start(BundleContext arg0) throws Exception {...}

public void bindService(@Observes @Contracts(StockQuoteService.class) ServiceEvents.ServiceArrival event) { System.out.println("bind : " + event.getServiceClassNames()); sqs = event.getService(ShapeProvider.class); System.out.println("Obtained StockQuotes:" + sqs.getSymbols()); }

by this way, while StockQuoteService is available, bindService as a Observer can be called back to inject StockQuoteService into sqs.


Sanjeeb Sahoo added a comment - 06/Nov/12 08:24 AM

Even the event integration approach won't ensure that injection happens before BundleActivator.start().

As I said earlier, I would keep it simple as we have done for OSGi/EJB and OSGi/Web. Once a bundle is ready (either ACTIVE or STARTING if activation-policy is lazy), we should scan the bundle and add the beans to the underlying CDI bean archive.

I don't like the approach of bootstrapping a CDI runtime inside BundleActivator.start(). If someone does that, then they are not leveraging OSGi/CDI integration and we should not care about those bundles.

BTW, can you add a marker header which must be present in a bundle to tell us that we should introspect the bundle as a CDI enabled bundle? Something like Meta-CDI header whose semantics can be same as Meta-Persistence header of OSGi/JPA spec. Only bundles having this header should be considered by OSGi/CDI layer.


TangYong added a comment - 06/Nov/12 08:47 AM

>Even the event integration approach won't ensure that injection happens before BundleActivator.start().
My means is that event integration should happen after BundleActivator.start() and similar to postConstruct function, and such a way, we recommend a user does not add logic related injection in BundleActivator.start().

>BTW, can you add a marker header which must be present in a bundle to tell us that we should introspect the bundle >as a CDI enabled bundle? Something like Meta-CDI header whose semantics can be same as Meta-Persistence header of >OSGi/JPA spec. Only bundles having this header should be considered by OSGi/CDI layer.
Hi sahoo, I think that this is not required because beans.xml has been a enabled flag that will be considered by OSGi/CDI layer.If the bundle does not contain beans.xml, it should be considered by OSGi/CDI layer and this also meets general rule of JSR 299.

>I don't like the approach of bootstrapping a CDI runtime inside BundleActivator.start(). If someone does that, then >they are not leveraging OSGi/CDI integration and we should not care about those bundles.
I want to say that you can not understand my means, when the user bootstrapps a CDI runtime inside BundleActivator.start(), in reality, he/she should use a medium to bootstrap and the medium is offered by OSGi/CDI layer. If he/she bootstrapps a CDI runtime using himself/herself medium, we should not care about these bundles.

>As I said earlier, I would keep it simple as we have done for OSGi/EJB and OSGi/Web. Once a bundle is ready >(either ACTIVE or STARTING if activation-policy is lazy), we should scan the bundle and add the beans to the >underlying CDI bean archive.
I can understand the point and activator's scene is a special use case, on such a use case, beans has been added, however, the use case cares about how to obtain these added beans. Of course, I maybe considered too much.

OK, let me leave the problem and do @publish related tests.


Sanjeeb Sahoo added a comment - 06/Nov/12 09:24 AM

1. As long as user does not use the injected field in activator.start(), it's fine.

2. Scanning every bundle for existence of META-INF/beans.xml is not correct. OSGi/JPA could have done the same for META-INF/persistence.xml. The issue here is before we scan a bundle, we need an explicit approval from the bundle whether it wants to be scanned or not. The presence of the header is considered as an approval. There is another reason for having the header. Imagine a scenario where the bundle wants to bootstrap CDI runtime itself bypassing OSGi/CDI integration facility. We can't support it unless we have such a header.

3. No, we can't provide an API to bootstrap CDI runtime. If user bootstraps themselves, we don't come into picture.


TangYong added a comment - 06/Nov/12 09:30 AM

OK, I will investigate and add such a head.
Thanks.

Tang


Sanjeeb Sahoo added a comment - 06/Nov/12 09:33 AM

Here are some basic requirements:
a) A CDI bean that's published as OSGi service must be using Singleton scope to match with lifecycle of OSGi services. e.g.,

@Publish
@Singleton
public class FooBean {}

In other words, following example must be treated as an error:
@Publish
public class FooBean {}

a) A CDI bean that's published as OSGi service must always consumed as an OSGi Service. In other words, following sample should fail as BarBean is trying to reference FooBean as a regular bean:

@Publish
@Singleton
public class FooBean {}

public class BarBean { @Inject FooBean foo; }

For it to work, it should look like this:
public class BarBean { @Inject @OSGiService FooBean foo; }

or
public class BarBean {
public void somemethod() { BundleContext bundleContext = // somehow obtain BundleContext bundleContext.getServiceReference(FooBean.class.getname(),...); }
}

Thanks,
Sahoo


TangYong added a comment - 06/Nov/12 09:42 AM

Thanks for clarifying test case's requirements.

Tang


Sivakumar Thyagarajan added a comment - 09/Nov/12 04:22 AM

It appears that in the patch you are resetting the SingletonProvider after a plain cdi osgi bundle deployment is complete. What happens if:
1. a CDI-enabled EAR was first depoyed (which would have setup the SingletonProvider in Weld to ACLSingletonProvider
2. A plain cdi osgi bundle is deployed, which would have reset the SingletonProvider to null.
3. Another CDI-enabled EAR is deployed. Since the ACLSingletonProvider was set only on the WeldActivator, the SingletonProvider would not be set to ACLSingletonProvider and hence this CDI-enabled EAR would use the default TCCLSingletonProvider. Isn't this wrong? Shouldn't we reset in step #2 to the earlier used SingletonProvider?


TangYong added a comment - 09/Nov/12 05:24 AM

Thanks siva's comments very much!

Yes, you are right, and I add a comment about SingletonProvider. When defaultly triggering bootstrap.startInitialization() using Weld SPI, SingletonProvider's instance is IsolatedStaticSingletonProvider. So, I made the following fix, and lately, I will attch my newest patch.

if (SingletonProvider.instance() instanceof IsolatedStaticSingletonProvider){ SingletonProvider.reset(); }

Thanks.
Tang


TangYong added a comment - 09/Nov/12 05:44 AM - edited

The attachment(GLASSFISH-19215-patch_20121109.zip) is my newest patch for this feature.

In addition, I added a GlassFish-CDIEnabled metadata handling logic according to sahoo's suggestion.


TangYong added a comment - 09/Nov/12 04:44 PM

Combined with sahoo and siva's comments and some issues found in integration tests, the newest patch has the following problems:

1 About SingletonProvider's initialize

Needs to consider multi-thread scene. I tried to directly start Weld-Integration bundle before triggering Weld-SPI , anything seemed to be fine. However, when combining with Weld Bootstrap's shutdown(now, handling logic is my local patch rather than appearing on my patch), because Weld-Integration's activate has a stop method which will reset SingletonProvider, we must take care of the point while managing Weld Bootstrap's shutdown in osgi-cdi module.

2 About position of publishing the beans

Better design is to make OSGiServiceExtension to publish beans in order that publish feature can work in hybrid javaee bundle.

The reason that I put the logic of publishing beans in OSGiCDIExtender is that I need to use Instance<object> to get bean service instance object, so we must get WeldManager, however, OSGiServiceExtension can not help me get Instance<object>.

3 About a exception called "WELD-001408 Unsatisfied dependencies "
After I deployed CDI OSGi Bundles, if I stop domain, and again start domain, deployed bundles should work normally, however, a exception happened in server.log,

org.glassfish.deployment.common.DeploymentException: WELD-001408 Unsatisfied dependencies for type [StockQuoteService] with qualifiers [@OSGiService] at injection point [[field] @Inject @OSGiService org.acme.cdiwab.impl.StockQuoteServlet.sqs]

4 About Weld Bootstrap's shutdown related handling
Doing.

Please siva and sahoo review in depth.

Thanks
Tang


TangYong added a comment - 12/Nov/12 06:24 AM

>2 About position of publishing the beans
>Better design is to make OSGiServiceExtension to publish beans in order that publish feature can work in hybrid >javaee bundle.
>The reason that I put the logic of publishing beans in OSGiCDIExtender is that I need to use Instance<object> to get >bean service instance object, so we must get WeldManager, however, OSGiServiceExtension can not help me get >Instance<object>.

I have confirmed that in OSGiServiceExtension.beforeBeanDiscovery method, adding the second parameter BeanManager manager can get SPI Manager(WeldManager), seeing following:

void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bdd, BeanManager manager){
debug("beforeBeanDiscovery" + bdd);
bdd.addQualifier(OSGiService.class); //XXX:needed?

if (manager instanceof WeldManager){ this.manager = (WeldManager)manager; }
}

Then, in afterBeanDiscovery method, executing publishOSGiService should be good and can work for hybrid javaee bundle.

However, once using the above way, in OSGiServiceExtension, we just put a cdi implementation's dependency called org.jboss.weld.manager.api, if not minding this, I think that the way should be good.

In addition, please seeing https://issues.jboss.org/browse/CDI-14, and maybe in the future, CDI Specification will add a portable method called "Instance<Object> instance()", so, I suggest that firstly we use the above way, then, once new api published, we can modify and use that new api.

Thanks.
-Tang


TangYong added a comment - 12/Nov/12 06:25 AM

>3 About a exception called "WELD-001408 Unsatisfied dependencies "
>After I deployed CDI OSGi Bundles, if I stop domain, and again start domain, deployed bundles should work normally, >however, a exception happened in server.log,

>org.glassfish.deployment.common.DeploymentException: WELD-001408 Unsatisfied dependencies for type >[StockQuoteService] with qualifiers [@OSGiService] at injection point [[field] @Inject @OSGiService >org.acme.cdiwab.impl.StockQuoteServlet.sqs]

I have sent two problems to you and siva and hong related the issue.

Tang


TangYong added a comment - 12/Nov/12 06:29 AM

>4 About Weld Bootstrap's shutdown related handling
>Doing.

I consider that the issue's priority should be lower than 1,2, and 3 and fighterfish related test cases.

I think that let me implement 1,2,3 and fighterfish test cases firstly.

Thanks.
Tang


TangYong added a comment - 14/Nov/12 12:23 PM

The attachment(GLASSFISH-19215-patch_20121114.zip) is the newest patch which has resolved 4 subtasks and passed my local integration test case.

Please sahoo and siva review it, and I will write fighterfish test cases(the fifth subtask).

Thanks.
Tang


TangYong added a comment - 22/Nov/12 02:27 PM

Combined with GLASSFISH-15365 and GLASSFISH-19359, I have added into fixing for them and made some adjustment of 19215.

Now, the attachment(GLASSFISH-19215_fighterfishtestcase_final_20121122.zip) has passed the fighterfish tests which I have uploaded in my local env.

Please sahoo and siva review and confirm the version.


TangYong added a comment - 05/Dec/12 12:06 PM

Yesterday, Siva has spent a lot of time to review my patch(GLASSFISH-19215_fighterfishtestcase_final_20121122.zip) and I arranged review contents in excel form in order to see and discuss them better. Please seeing attachment(reviewing_siva.xls).


TangYong added a comment - 10/Dec/12 12:36 PM

Current fixing state has been uploaded, please seeing reviewing_siva_2012.12.10.xls


TangYong added a comment - 11/Dec/12 08:19 AM

Currently, all problems from review other than splitting patch and needing to discuss have been fixed, about status, please seeing reviewing_siva_2012.12.11.xls.

Tomorrow, I will finish the working of splitting patch.


TangYong added a comment - 11/Dec/12 09:05 AM

Splited patch for Glassfish-19215 is uploaded, please seeing GLASSFISH-19215-patch-20121211.zip