Thinking about this more, I am just not sure if the use case is a good
one or not.
It seems like you want something that manages your component's
implementation details, but this doesn't really make sense. For a
primitive component (i.e., one that is a Java class), it doesn't make
sense that the container would know about and manage the implementation
details, since those details are Java code.
The only way this makes sense is if the component is a composite
component, i.e., the container is given a description of the internals
of the component, then the container is responsible for everything
inside of the component. This is how iPOJO composites work. You describe
the composition of your component (i.e., its implementation) and then
iPOJO is able to create and manage isolated instances of this composite
component like any normal component.
-> richard
Richard S. Hall wrote:
Miroslav Nachev wrote:
In "Hello Service Client using Annotations" project I am added the
following class:
package ipojo.example;
import ipojo.example.hello.Hello;
import org.apache.felix.ipojo.annotations.Requires;
public class ExtraBean
{
@Requires
private Hello[] m_hello;
public ExtraBean()
{
System.out.println("ExtraBean.m_hello: " + m_hello);
}
public String doWork()
{
return "Miro";
}
}
Then I use that class in HelloClient.invokeHelloServices() as follow:
ExtraBean extraBean = new ExtraBean();
System.out.println("extraBean.doWork(): " + extraBean.doWork());
iPOJO does not support this use case, since you want to create the
instance yourself. For iPOJO to manage the instance, it must create
it. You could perhaps get around this by using iPOJO factories to
create your instance:
http://felix.apache.org/site/how-to-use-ipojo-factories.html
The error result when the bundle is started is:
ERROR: Error starting
file:../hello.client.annotation/target/hello.client.annotation-0.8.0-SNAPSHOT.jar
(org.osgi.framework.BundleException: Unresolved constraint in bundle
10: package; (package=ipojo.example))
org.osgi.framework.BundleException: Unresolved constraint in bundle
10: package; (package=ipojo.example)
at
org.apache.felix.framework.Felix._resolveBundle(Felix.java:1741)
at org.apache.felix.framework.Felix._startBundle(Felix.java:1604)
at org.apache.felix.framework.Felix.startBundle(Felix.java:1548)
at
org.apache.felix.framework.Felix.setFrameworkStartLevel(Felix.java:1142)
at
org.apache.felix.framework.StartLevelImpl.run(StartLevelImpl.java:265)
at java.lang.Thread.run(Unknown Source)
Perhaps your service object is not exporting this package? But the use
case is still not going to work.
-> richard
Miro.
Clement Escoffier wrote:
Hi,
I will complete a little Richard's answer :-):
The temporal dependency accepts several arguments:
- timeout : setting the timeout time
- onTimeout : defines the action to do when the timeout occurs.
When requesting a temporal dependency, the thread is stopped until
the service appears or the timeout is reached (3s by default, set
the timeout to -1 to wait forever). When the timeout is reached, you
can define an action. By default a RuntimeException is thrown. But,
you can set the onTimeout action to do:
- null: injects null
- nullable: injects a fake service object that does nothing
- empty-array: injects an empty array (only for aggregate dependencies)
- a class name : this class name is used as default-implementation.
So, an instance of this class is created. This class must implement
the service interface and you can implement your own behavior.
So, with this temporal dependency you can create a smart proxy
delegating call to the service and managing the dynamism.
Clement
-----Original Message-----
From: Richard S. Hall [mailto:[EMAIL PROTECTED] Sent: vendredi
17 octobre 2008 15:26
To: [email protected]
Subject: Re: Dependency Injection with annotations
Miroslav Nachev wrote:
Hello Clement,
In traditional way if I have some OSGi Service which have to be
used in some class (POJO Bean) I MUST pass this service to one or
more classes as parameter. Then when the time for using of that
service is on the service can be unavailable. Similar problem I
will have when I want to stop my bundle. That's why if iPOJO
Annotations allow some service to be used inside of the bundle will
be perfect. This can be done with Proxy. When I create some new
object with new JavaClass(...) and in that object I am declared
some OSGi Service using iPOJO Annotation, that service will point
to some Proxy which proxy will try to get the service on request.
This will guarantee that the service is actual independently how
much the service is restarted and updated. In traditional way the
application must track all service states and etc. Passing the
service as parameter complicate the things.
Did you have some plans iPOJO to support the above scenario?
I am not totally sure I understand your scenario, but it sounds like
you want a proxy that only tries to get the service when someone
tries to use it. iPOJO does not support this type of scenario
automatically, but it is fairly easy to achieve. Assume you have the
following service:
public interface Foo {
void doFoo();
}
You could create a component like this:
import org.apache.felix.ipojo.temporal.Requires;
public class MyFooProxy implements Foo {
@Requires
private Foo m_foo;
public void doFoo() {
m_foo.doFoo();
}
}
The dependency on m_foo is declared to be temporal, which means that
it will only try to get the service when it is used. If one is not
available, it will eventually timeout and throw an exception. Now
you should be able to pass this "proxy" component to you components
and they will be able to use the service on demand.
-> richard
Regards,
Miro.
clement escoffier wrote:
2008/10/14 Stuart McCulloch <[EMAIL PROTECTED]>
2008/10/14 Miroslav Nachev <[EMAIL PROTECTED]>
Hi,
This is very interesting and I will try it but this answer is
half of my
question. I am interesting how to get some service in my code,
not in
another service. For example:
public class SomePOJOBean
{
@Requires
??? how to pass some parameters to the service (passive,
dynamics)
private FooService foo;
}
How can be implemented the above scenario?
So, as I understand, you don't want (global) services but your own
(customized) service. As you're configuring the service, this
service should
not be available to other consumers. In iPOJO you can do this by
using
composites (the new documentation is coming soon). Composites
assert that
your service is isolated. However, composites does not allows you
to declare
those services in your code.
Well, iPOJO injects components - but these are not necessarily
services.
Clement's example happened to provide a service, but this isn't
mandatory.
You do need to tell iPOJO about your code somehow, and in iPOJO
this is
done
by marking them as components which iPOJO injects as necessary.
(I'm sure
Clement can explain this better than me!)
Service providing is (of course) not necessary. Your component can
be a
component that does not provide a service (like a GUI).
Clement
There are also alternative ways to inject OSGi services, using
(non-OSGi)
dependency injection frameworks:
* Spring has the Spring-DM extension, but I don't know if it fully
supports
configuration via annotation.
http://www.springframework.org/osgi/
* Guice has the peaberry extension, which I work on - in this
case the
service configuration is done in the binding module, not the
annotation (I
did look at doing annotation configuration, but this rapidly
becomes a
management nightmare)
http://code.google.com/p/peaberry/
HTH
Regards,
Miro.
clement escoffier wrote:
Hi,
iPOJO provides such annotations as:
@Component
@Provides // Provides a service
public class Foo implements Service {
@Requires // Service dependency
private HelloService hello;
...
}
You can find further info at
http://felix.apache.org/site/how-to-use-ipojo-annotations.html
About parameters, the iPOJO's way is to inject instance
property. Those
fields will be set before the execution of your constructor
(between the
super constructor invocation and the constructor code), and your
constructor
can use those fields, such as in:
@Component
@Provides // Provides a service
public class Foo implements Service {
@Property
private String myString;
@Requires // Service dependency
private HelloService hello;
public Foo() {
// Can use myString here as well as hello
}
...
}
Regards,
Clement
2008/10/14 Miroslav Nachev <[EMAIL PROTECTED]>
Hi,
I would like to ask you about some way in Felix to export
services in
more
easy way only with annotation like in EJB3.x: @Stateful,
@Stateless,
@Remote, @Local, @EJB, etc.
In my opinion the best way this to be done is inside of the OSGi
framework.
Then all resources (services) can be exported to the framework
just
with
annotation. The same for needed services. What about if before
to get
some
service we have to pass some parameters to the constructor?
Regards,
Miro.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
--
Cheers, Stuart
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]