Multiple bundles dependencies injection (pax-cdi or blueprint)

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
Hello,
I'm new to osgi world (coming from a JEE bck) and trying to use pax-cdi at first to manage injection.
I have 3 bundles
Bundle A declares an interface:
package com.eg;
public interface Itf {
        public void PrintITf();

}


with Manifest generation using maven:
<Export-Package>com.eg*</Export-Package>


Bundle B implements this interface:
package com.eg.impl;
public class ItfImpl implements Itf {

        public void PrintIFy() {
                System.out.println("Hello");
        }
}


<Import-Package>
com.eg*,*
</Import-Package>

Bundle C is trying to inject Itf (as it can be done using JEE):
@Inject
        private Itf itf;
        public void setItf(Itf itf) {
                this.itf= itf;
        }
       
        public Use() {
                itf.PrintIFy();
        }

<Import-Package>
com.eg*, com.eg.impl*, *
</Import-Package>
<Require-Capability>
osgi.extender;
filter:="(osgi.extender=pax.cdi)",
org.ops4j.pax.cdi.extension;
filter:="(extension=pax-cdi-extension)"
</Require-Capability>

It doesn't seem to work as I always get NullPointerException starting bundle C.

is this a classical use case in OSGI framework?
Do you think I should change the way I split these 3 bundles (moving interface and implementation in the same bundle)?

I also tried with blueprint without being able to do it as well...
thanks for your help
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

Achim Nierbeck
Hi, 

just some comments from the peanut gallery :-)

If you just want to wire services between different bundles, stick with DS. 
If you also want to have the full Context and Dependency injection stuff within your own bundle, for example some inner bundle bean wiring. 
In that case go with Pax-CDI.
If you want to have servlets combined with services sometimes DS is enough. 
If you want to have a full-blown WAR with lot's of different stuff in it, Pax-CDI might be the solution, to reference external services. 

So this solely depends on the use-case and how good you are in cutting dependencies. 

regards, Achim 



2017-03-06 11:04 GMT+01:00 erwan <[hidden email]>:
Hello,
I'm new to osgi world (coming from a JEE bck) and trying to use pax-cdi at
first to manage injection.
I have 3 bundles
Bundle A declares an interface:
/package com.eg;
public interface Itf {
        public void PrintITf();

}/

with Manifest generation using maven:
<Export-Package>com.eg*</Export-Package>


Bundle B implements this interface:
/package com.eg.impl;
public class ItfImpl implements Itf {

        public void PrintIFy() {
                System.out.println("Hello");
        }
}/

<Import-Package>
com.eg*,*
</Import-Package>

Bundle C is trying to inject Itf (as it can be done using JEE):
/@Inject
        private Itf itf;
        public void setItf(Itf itf) {
                this.itf= itf;
        }

        public Use() {
                itf.PrintIFy();
        }/
<Import-Package>
com.eg*, com.eg.impl*, *
</Import-Package>
<Require-Capability>
osgi.extender;
filter:="(osgi.extender=pax.cdi)",
org.ops4j.pax.cdi.extension;
filter:="(extension=pax-cdi-extension)"
</Require-Capability>

It doesn't seem to work as I always get NullPointerException starting bundle
C.

is this a classical use case in OSGI framework?
Do you think I should change the way I split these 3 bundles (moving
interface and implementation in the same bundle)?

I also tried with blueprint without being able to do it as well...
thanks for your help



--
View this message in context: http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756.html
Sent from the Karaf - User mailing list archive at Nabble.com.



--

Apache Member
Apache Karaf <http://karaf.apache.org/> Committer & PMC
OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer & Project Lead
blog <http://notizblog.nierbeck.de/>
Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>

Software Architect / Project Manager / Scrum Master 

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
Thanks for your quick reply.
What I have in mind is separate a persistence implementation in a bundle, with an interface exposed to several other bundles in a second bundle (like a pseudo shared bundle maybe?), these several other bundles using interface injected.

getting back to the previous code, I wasn't able to make it working, so probably not really good cutting dependencies
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

Timothy Ward
Hi,

That sounds a lot like you’re building a persistence service with a defined API (a good thing!). As I think you’ve already realised, you will want to start by defining the persistence service and the DTOs that it is responsible for persisting/retrieving. These things should live in an API bundle which is shared by the persistence implementation and the clients.

After that I can recommend using Transaction Control in the persistence bundle to implement the persistence layer (see http://aries.apache.org/modules/transactioncontrol.html), and using Declarative Services to provide/consume services.

The rest of the client bundles can then be written however you want, but again, I can recommend Declarative Services.

Regards,

Tim

On 6 Mar 2017, at 10:26, erwan <[hidden email]> wrote:

Thanks for your quick reply.
What I have in mind is separate a persistence implementation in a bundle,
with an interface exposed to several other bundles in a second bundle (like
a pseudo shared bundle maybe?), these several other bundles using interface
injected.

getting back to the previous code, I wasn't able to make it working, so
probably not really good cutting dependencies



--
View this message in context: http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756p4049758.html
Sent from the Karaf - User mailing list archive at Nabble.com.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

cschneider
In reply to this post by erwan
A simple @Inject only works inside a bundle.
If you want to inject an object from another bundle then Export the
object as a service in bundle B and inject it as a service in bundle C.

Btw. using the blueprint-maven-plugin you can even use the CDI/JEE
annotations for blueprint.

See this to inject a service:
https://github.com/cschneider/Karaf-Tutorial/blob/master/tasklist-blueprint-cdi/tasklist-service/src/main/java/net/lr/tasklist/service/impl/TaskServiceRest.java#L31

and this to offer a service:
https://github.com/cschneider/Karaf-Tutorial/blob/master/tasklist-blueprint-cdi/persistence/src/main/java/net/lr/tasklist/persistence/impl/TaskServiceImpl.java#L18

The approach works with both pax-cdi and blueprint with the
blueprint-maven-plugin.

Having said this I support what Achim said. In many cases it is even
better to use declarative services instead as they are better tailored
for OSGi.
In your case CDI might be the better choice as you have more experience
with it but I would experiment with both.

Christian

On 06.03.2017 11:04, erwan wrote:

> Hello,
> I'm new to osgi world (coming from a JEE bck) and trying to use pax-cdi at
> first to manage injection.
> I have 3 bundles
> Bundle A declares an interface:
> /package com.eg;
> public interface Itf {
> public void PrintITf();
>
> }/
>
> with Manifest generation using maven:
> <Export-Package>com.eg*</Export-Package>
>
>
> Bundle B implements this interface:
> /package com.eg.impl;
> public class ItfImpl implements Itf {
>
> public void PrintIFy() {
> System.out.println("Hello");
> }
> }/
>
> <Import-Package>
> com.eg*,*
> </Import-Package>
>
> Bundle C is trying to inject Itf (as it can be done using JEE):
> /@Inject
> private Itf itf;
> public void setItf(Itf itf) {
> this.itf= itf;
> }
>
> public Use() {
> itf.PrintIFy();
> }/
> <Import-Package>
> com.eg*, com.eg.impl*, *
> </Import-Package>
> <Require-Capability>
> osgi.extender;
> filter:="(osgi.extender=pax.cdi)",
> org.ops4j.pax.cdi.extension;
> filter:="(extension=pax-cdi-extension)"
> </Require-Capability>
>
> It doesn't seem to work as I always get NullPointerException starting bundle
> C.
>
> is this a classical use case in OSGI framework?
> Do you think I should change the way I split these 3 bundles (moving
> interface and implementation in the same bundle)?
>
> I also tried with blueprint without being able to do it as well...
> thanks for your help
>
>
>
> --
> View this message in context: http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756.html
> Sent from the Karaf - User mailing list archive at Nabble.com.


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
Thanks for your support.
Let's jump into documentation
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

Tim Jones
This is a bit long winded but as you are new to OSGi before you make your next step ...
As you have probably realised by now there are a few ways of achieving your goal, it can be difficult trying to distill the information on the Web and come up with the 'best' way to wire up services between bundles. Even in this one thread three different ways have been mentioned, Pax-CDI, Blueprint (of which there are 2 flavours) and Declarative Services, there are  others not mentioned. Unfortunately you are unlikely to get a general consensus as to the best way forward and even that may depend on what you are ultimately trying to achieve. But some of the things that you may want to take into consideration before opting for a particular technology is whether it is widely used, backed by a specification e.g. OSGi Alliance, has there been any recent enhancements to the specification, are there any new specifications that may effect your decision, does the technology offer the life cycle dynamics that OSGi can provide. Take CDI for example, as mentioned above there is already an implementation, Pax-CDI, the OSGi Alliance has also a published https://github.com/osgi/design/blob/master/rfcs/rfc0193/rfc-0193-CDI-Integration.pdf, how will this effect the Pax-CDI project? Is there another implementation on its way? Take Aries Blueprint, it is widely used but from my understanding the Blueprint specification has not been touched for 5 years or so since it was first released in OSGi 4.2. Take Declarative Services as another example, this technology is widely used, has recent specification enhancements, is enthusiastically promoted by the founder of the enroute project (http://enroute.osgi.org/), promoted by the bndtools community, but at the moment takes a bit more work to integrate with other technologies such as CXF, Camel than say Aries Blueprint, although I think there is good work going on in these projects to make it easier. Another consideration is although it may be seemingly possible to do something in a certain way, can you have a high level of confidence that the library has extensive tests to support it. As an example, my company recently engaged Paremus to write the the tx-control project which underpins the transaction management of our system, there are over 3500 lines of test code in that project. I think you would agree that for something as fundamental as transactional management of persistence you really want a high level of confidence that it does work and wont be easily inadvertently broken in later releases (obviously unashamedly trying to convince you of the merits of tx-control :)

Hope this helps,

Tim
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
Sorry for the "timeout" before answering your comment but it took me some time to have a look at all solutions that were proposed. What strikes me is that, as you already stated, it is difficult to select a solution that is simple, well documented and seen as a standard. It's a bit annoying as osgi doesn't seem to be a young solution. By browsing the web, looking for solutions, it seems to go in every directions.
To be more concrete, I tried to combine 2 solutions to my need : blueprint and DS.
I'm not sure we can mix several solutions. I probably need to spend some more time :)
First, I use blueprint solution to deploy a persistence bundle and Christian tutorial site has been of a great help with that. Thanks to you.
Then I tried to add declarative service in the loop, using annotations as it seemed practical to me.
For the moment, I'm not able to make this working so I hope you might take a little bit more time to evangelize
Can I do this?
In the persistence bundle, after having installed hibernate feature:

@Component(immediate = true)
@Transactional
public class RepositoryImpl implements IRepository {

        private EntityManager manager;

        @PersistenceContext(unitName="db")
        public void setEntityManager(EntityManager manager) {
                this.manager = manager;
        }

        private UniqueIdManagerItf uniqueIdManager;

        @Reference
        public void setUniqueIdManager(UniqueIdManagerItf uniqueIdManager) {
                this.uniqueIdManager = uniqueIdManager;
        }

        @Override
        public void removeAll() {
                ArrayList<String> uniqueIdList = new ArrayList<>();

                uniqueIdList = uniqueIdManager.getUniqueIdList();
                for (String id: uniqueIdList) {
                        uniqueIdManager.setIdAsAvailable(id);
                }
                manager.createQuery("DELETE FROM MyEntity").executeUpdate();
        }

with a pom like this:
                                <configuration>
                                        <instructions>
                                                <Bundle-SymbolicName>${project.artifactId}</Bundle-symbolicName>
                                                <Bundle-Version>${project.version}</Bundle-Version>
                                                <supportedProjectTypes>
                                                        <supportedProjectType>bundle</supportedProjectType>
                                                </supportedProjectTypes>
                                                <Export-Package>
                                                com.example.persistence.entity.*;version=${project.version}
                                                </Export-Package>
                                                <Import-Package>
                                                        *
                                                </Import-Package>
                                                <Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
                                                <Dynamic-Import-Package>
                                                        *,
                                                        org.hibernate.proxy,
                                                        javassist.util.proxy
                                                </Dynamic-Import-Package>
                                                <_dsannotations>*</_dsannotations>
                                        </instructions>
                                </configuration>

a persistence.xml :
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">

  <persistence-unit name="db" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=db)</jta-data-source>
        <class>com.example.persistence.entity.MyEntity</class>
       
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
      <property name="hibernate.archive.autodetection" value="class"/>
    </properties>

  </persistence-unit>

</persistence>

and what might be unnecessary :
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" 
                   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0" 
                   xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.2.0" 
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
        <jpa:enable/>
        <tx:enable-annotations/>
</blueprint>

In the consumer bundle (something like a REST api):

@Path("")
@Component
public class EndPoint {

        private IRepository repository;
        @Reference
        public void setRepository(IRepository repository) {
                this.repository = repository;
        }

        @DELETE
        @Path("removeAll")
        public void  clearDB() {
                repository.removeAll();

        }

With a third bundle API:
public interface IRepository {
        void removeAll();

in this example, I think i'm missing something that will instantiate the IRepository although I thought it will be done by the declarative service. I also think that I probably didn't understand well how it works internally.

On karaf side:
scr:details com.example.persistence.JPAResourceRepositoryImpl
Component Details
  Name                : com.example.persistence.JPAResourceRepositoryImpl
  State               : ACTIVE
References
  Reference           : UniqueIdManager
    State             : satisfied
    Multiple          : single
    Optional          : mandatory
    Policy            : static
    Service Reference : Bound Service ID 556 (com.example.persistence.UniqueIdManager)

As you can understand, I really need more reading sessions of the chapter 5 inside OSGi Core document!
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

cschneider
The @Transactional and @PersistenceContext annotations work exclusively
in blueprint or eventually pax-cdi with deltaspike.

For declarative services there is no extension model to add new
annotations. So we can not easily support annotations like above.
This is not a big issue though as we have alternative solutions in place.

See
http://liquid-reality.de/display/liquid/2015/06/30/Apache+Karaf+Tutorial+part+10+-+Declarative+services

For DS there is the JPATemplate from Aries JPA. It allows the same
feature set as the annotations for blueprint but works using closures
instead.
I used this a bit myself and while I first was very pro annotation I
changed my mind in the mean time. I think the closure based approach works
as nice and is less complex. Btw. I am experimenting with an alternative
approach using try with resources instead of closures. That would allow
a similar style but be even less complex.

There is also an alternative from the OSGi specs. It is called
tx-control and also hosted at Aries.
http://aries.apache.org/modules/tx-control/
It is similar to JPATemplate but a little different in style. The code
is written by Tim Ward and he also did a very good documentation for it.

Christian

On 10.03.2017 09:00, erwan wrote:

> Sorry for the "timeout" before answering your comment but it took me some
> time to have a look at all solutions that were proposed. What strikes me is
> that, as you already stated, it is difficult to select a solution that is
> simple, well documented and seen as a standard. It's a bit annoying as osgi
> doesn't seem to be a young solution. By browsing the web, looking for
> solutions, it seems to go in every directions.
> To be more concrete, I tried to combine 2 solutions to my need : blueprint
> and DS.
> I'm not sure we can mix several solutions. I probably need to spend some
> more time :)
> First, I use blueprint solution to deploy a persistence bundle and Christian
> tutorial site has been of a great help with that. Thanks to you.
> Then I tried to add declarative service in the loop, using annotations as it
> seemed practical to me.
> For the moment, I'm not able to make this working so I hope you might take a
> little bit more time to evangelize
> Can I do this?
> In the persistence bundle, after having installed hibernate feature:
>
> @Component(immediate = true)
> @Transactional
> public class RepositoryImpl implements IRepository {
>
> private EntityManager manager;
>
> @PersistenceContext(unitName="db")
> public void setEntityManager(EntityManager manager) {
> this.manager = manager;
> }
>
> private UniqueIdManagerItf uniqueIdManager;
>
> @Reference
> public void setUniqueIdManager(UniqueIdManagerItf uniqueIdManager) {
> this.uniqueIdManager = uniqueIdManager;
> }
>
> @Override
> public void removeAll() {
> ArrayList<String> uniqueIdList = new ArrayList<>();
>
> uniqueIdList = uniqueIdManager.getUniqueIdList();
> for (String id: uniqueIdList) {
> uniqueIdManager.setIdAsAvailable(id);
> }
> manager.createQuery("DELETE FROM MyEntity").executeUpdate();
> }
>
> with a pom like this:
> <configuration>
> <instructions>
> <Bundle-SymbolicName>${project.artifactId}</Bundle-symbolicName>
> <Bundle-Version>${project.version}</Bundle-Version>
> <supportedProjectTypes>
> <supportedProjectType>bundle</supportedProjectType>
> </supportedProjectTypes>
> <Export-Package>
> com.example.persistence.entity.*;version=${project.version}
> </Export-Package>
> <Import-Package>
> *
> </Import-Package>
> <Meta-Persistence>META-INF/persistence.xml</Meta-Persistence>
> <Dynamic-Import-Package>
> *,
> org.hibernate.proxy,
> javassist.util.proxy
> </Dynamic-Import-Package>
> <_dsannotations>*</_dsannotations>
> </instructions>
> </configuration>
>
> a persistence.xml :
> <persistence xmlns="http://java.sun.com/xml/ns/persistence"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
>
>    <persistence-unit name="db" transaction-type="JTA">
>      <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>    
> <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=db)</jta-data-source>
> <class>com.example.persistence.entity.MyEntity</class>
>
>      <properties>
>        <property name="hibernate.dialect"
> value="org.hibernate.dialect.H2Dialect"/>
>        <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
>        <property name="hibernate.archive.autodetection" value="class"/>
>      </properties>
>
>    </persistence-unit>
>
> </persistence>
>
> and what might be unnecessary :
> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>   xmlns:tx="http://aries.apache.org/xmlns/transactions/v1.2.0"
>   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
> https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
> <jpa:enable/>
> <tx:enable-annotations/>
> </blueprint>
>
> In the consumer bundle (something like a REST api):
>
> @Path("")
> @Component
> public class EndPoint {
>
> private IRepository repository;
> @Reference
> public void setRepository(IRepository repository) {
> this.repository = repository;
> }
>
> @DELETE
> @Path("removeAll")
> public void  clearDB() {
> repository.removeAll();
>
> }
>
> With a third bundle API:
> public interface IRepository {
> void removeAll();
>
> in this example, I think i'm missing something that will instantiate the
> IRepository although I thought it will be done by the declarative service. I
> also think that I probably didn't understand well how it works internally.
>
> On karaf side:
> scr:details com.example.persistence.JPAResourceRepositoryImpl
> Component Details
>    Name                : com.example.persistence.JPAResourceRepositoryImpl
>    State               : ACTIVE
> References
>    Reference           : UniqueIdManager
>      State             : satisfied
>      Multiple          : single
>      Optional          : mandatory
>      Policy            : static
>      Service Reference : Bound Service ID 556
> (com.example.persistence.UniqueIdManager)
>
> As you can understand, I really need more reading sessions of the chapter 5
> inside OSGi Core document!
>
>
>
>
> --
> View this message in context: http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756p4049823.html
> Sent from the Karaf - User mailing list archive at Nabble.com.


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
I'm still working on a solution for my problem and for the moment Reference injected doesn't seem to be filled.
I'm getting a NullPointerException every time I'm trying to access methods on this @Reference.
What is difficult is that I found some key information in several sources. For example, I found these lines in hibernate site:
"Technically, multiple persistence units are supported by Enterprise OSGi JPA and unmanaged Hibernate JPA use. However, we cannot currently support this in OSGi. In Hibernate 4, only one instance of the OSGi-specific ClassLoader is used per Hibernate bundle, mainly due to heavy use of static TCCL utilities. We hope to support one OSGi ClassLoader per persistence unit in Hibernate 5.
Scanning is supported to find non-explicitly listed entities and mappings. However, they MUST be in the same bundle as your persistence unit (fairly typical anyway). Our OSGi ClassLoader only considers the "requesting bundle" (hence the requirement on using services to create EMF/SF), rather than attempting to scan all available bundles. This is primarily for versioning considerations, collision protections, etc. "

I also see that a @Reference seems to be only taken into account inside a @Component? is this right?

Maybe the way I use DS with hibernate isn't possible.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

cschneider
You are right.

@Reference is only meaningful in an @Component. So this only works if
your class is instantiated by DS.

If you want to use DS then I strongly recommend to start with my
tutorial code:
https://github.com/cschneider/Karaf-Tutorial/tree/master/tasklist-ds

So at least you have a working base.

Again - Do not mix blueprint and DS in the same bundle. Choose one and
use it for all classes in a bundle.

Christian

On 15.03.2017 09:21, erwan wrote:

> I'm still working on a solution for my problem and for the moment Reference
> injected doesn't seem to be filled.
> I'm getting a NullPointerException every time I'm trying to access methods
> on this @Reference.
> What is difficult is that I found some key information in several sources.
> For example, I found these lines in hibernate site:
> "Technically, multiple persistence units are supported by Enterprise OSGi
> JPA and unmanaged Hibernate JPA use. However, we cannot currently support
> this in OSGi. In Hibernate 4, only one instance of the OSGi-specific
> ClassLoader is used per Hibernate bundle, mainly due to heavy use of static
> TCCL utilities. We hope to support one OSGi ClassLoader per persistence unit
> in Hibernate 5.
> Scanning is supported to find non-explicitly listed entities and mappings.
> However, they MUST be in the same bundle as your persistence unit (fairly
> typical anyway). Our OSGi ClassLoader only considers the "requesting bundle"
> (hence the requirement on using services to create EMF/SF), rather than
> attempting to scan all available bundles. This is primarily for versioning
> considerations, collision protections, etc. "
>
> I also see that a @Reference seems to be only taken into account inside a
> @Component? is this right?
>
> Maybe the way I use DS with hibernate isn't possible.
>
>
>
> --
> View this message in context: http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756p4049851.html
> Sent from the Karaf - User mailing list archive at Nabble.com.


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
Ok thanks Christian.
I manage to make things work after moving cxf part from blueprint xml description to component property elements.
For cxf, it seems to be really sensible to configuration as I wasn't able to give a "/" as org.apache.cxf.servlet.context and neither was able to configure "org.apache.cxf.rs.address=/" in properties. Anyway, my requests are received using curl and processed to the database.
I still have issues coming from injected fields.
Can you confirm also that I can't use @Inject in @Component annotated class?
I thought it was possible to inject classes within the same bundle and inside a @Component annotated class.
I don't really understand why all these solutions are exclusive as well...
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

cschneider
Indeed you can not use @Inject in DS. Instead use @Reference and make
sure you export the class you want to inject using @Component.
Each dependency injection solution has a certain set of annotations with
slightly different abilities and limitations.

Christian

On 15.03.2017 16:46, erwan wrote:

> Ok thanks Christian.
> I manage to make things work after moving cxf part from blueprint xml
> description to component property elements.
> For cxf, it seems to be really sensible to configuration as I wasn't able to
> give a "/" as org.apache.cxf.servlet.context and neither was able to
> configure "org.apache.cxf.rs.address=/" in properties. Anyway, my requests
> are received using curl and processed to the database.
> I still have issues coming from injected fields.
> Can you confirm also that I can't use @Inject in @Component annotated class?
> I thought it was possible to inject classes within the same bundle and
> inside a @Component annotated class.
> I don't really understand why all these solutions are exclusive as well...
>
>
>
>
> --
> View this message in context: http://karaf.922171.n3.nabble.com/Multiple-bundles-dependencies-injection-pax-cdi-or-blueprint-tp4049756p4049853.html
> Sent from the Karaf - User mailing list archive at Nabble.com.


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

erwan
Hello,
Coming back again to get light!
I have a bundle of questions regarding DS.
How do you use a service without being yourself a service?

I understand that each service is managed by the scr and so need to be activated at a time. If I have a class that need to do a reference to a service but that I want to control instantiation, is this possible to instantiate a service on demand (newInstance?) ?

How do you manage to deal with multiple instances of a service?
For example:

class dummy {

@Reference
private Service service1

@Reference
private Service service2

}
How to get service1 and service2 referring to 2 different classes?

How can we do this kind of idea (Completely false!!!):
@Component
class dummy {
@Reference
private Service service1 = new Service(); <= only the principle :)

@Reference
private Service service2 = new Service(); <= only the principle :)

}
Thanks.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

cschneider
On 28.03.2017 11:07, erwan wrote:
> Hello,
> Coming back again to get light!
> I have a bundle of questions regarding DS.
> How do you use a service without being yourself a service?
You can not use a service without being a service in DS. You can hide
your service though.
If you set serviceClass to a class in a private package then no other
bundle can use this service.
So this works nicely if you have some internal wiring.
>
> I understand that each service is managed by the scr and so need to be
> activated at a time. If I have a class that need to do a reference to a
> service but that I want to control instantiation, is this possible to
> instantiate a service on demand (newInstance?) ?
I think you can create a DS component instance programmatically but I do
not remember any more how to do it exactly.

>
> How do you manage to deal with multiple instances of a service?
> For example:
>
> class dummy {
>
> @Reference
> private Service service1
>
> @Reference
> private Service service2
>
> }

For this case you typically use a filter and set a service property on
each of the implementing classes.

Btw you can even set a service property for a DS service that you have
not written.
See
http://liquid-reality.de/display/liquid/2016/09/27/Some+hints+to+boost+your+productivity+with+declarative+services
Paragraph "Override service properties using config "

Christian


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Multiple bundles dependencies injection (pax-cdi or blueprint)

David Jencks-2
There are some inaccuracies in what Christian wrote.

On Mar 28, 2017, at 2:19 AM, Christian Schneider <[hidden email]> wrote:

On 28.03.2017 11:07, erwan wrote:
Hello,
Coming back again to get light!
I have a bundle of questions regarding DS.
How do you use a service without being yourself a service?
You can not use a service without being a service in DS. You can hide your service though.
If you set serviceClass to a class in a private package then no other bundle can use this service.
So this works nicely if you have some internal wiring.

A DS component does not have to expose any service interfaces.  Such a component will not be registered as a service.  It will be immediate and a singleton.
If you are using the DS spec annotations, the default service property is all the directly implemented interfaces of your class, so if there are no such interfaces, by default your component will not be registered as a service; otherwise you have to specify service={} in the @Component annotation.


I understand that each service is managed by the scr and so need to be
activated at a time. If I have a class that need to do a reference to a
service but that I want to control instantiation, is this possible to
instantiate a service on demand (newInstance?) ?
I think you can create a DS component instance programmatically but I do not remember any more how to do it exactly.

You can try to use a factory component but these have a very peculiar lifecycle that in my experience makes them impossible to understand and useless.  For instance, I’ve been trying to explain their behavior for a couple months to someone on the felix lists.  There’s a felix-proprietary extension @DSExt.PersistentFactoryComponent  that makes the lifecycle like a normal component, but I would strongly advise seeking another solution.

I would consider whether some combination of configuring several service instances of the same DS component using factory configurations and/or using prototype scope would meet your needs.


How do you manage to deal with multiple instances of a service?
For example:

class dummy {

@Reference
private Service service1

@Reference
private Service service2

}

For this case you typically use a filter and set a service property on each of the implementing classes.

Btw you can even set a service property for a DS service that you have not written.
See http://liquid-reality.de/display/liquid/2016/09/27/Some+hints+to+boost+your+productivity+with+declarative+services
Paragraph "Override service properties using config “

This reference is mostly correct except for claiming that components must expose services.  I think it would be helpful if it provided an example of filter syntax (people often leave off the parentheses the first time) and pointed out that all the @Reference choices are available for the event strategy (and indeed lookup strategy) by explicitly specifying them in the @Reference annotation.  While I think it’s pretty likely that constructor injection will still be in the R7 spec when it comes out I prefer not to assert such things categorically.

thanks
david jencks


Christian


--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com


Loading...