Annotated Style service not working on JBoss AS7

180 views
Skip to first unread message

Luca Merolla

unread,
Dec 5, 2011, 8:59:12 AM12/5/11
to cometd-users
Hello everyone,

I'm trying to understand why I cannot use the annotated style services
on JBoss AS 7.0.2. In particular, during the deployment I get an
exception

WELD-001408 Unsatisfied dependencies for type [BayeuxServer] with
qualifiers [@Default] at injection point [[field] @Inject private
org.test.cometd.service.TestService.server

The problem seems to be that the BayeuxServer is not a bean and cannot
be instantiated by the CDI.
How can I work around this issue? I thought about adding a beans.xml
file to the CometD jar libraries, but I don't think is the right way
to fix it.

PS=I'm using CometD 2.4.0.RC1. For more details on the error I have
posted also on the JBoss forums (http://community.jboss.org/thread/
175697).

Thanks in advance,
LM

Simone Bordet

unread,
Dec 5, 2011, 12:29:47 PM12/5/11
to cometd...@googlegroups.com
Hi,

On Mon, Dec 5, 2011 at 14:59, Luca Merolla <luca.m...@gmail.com> wrote:
> Hello everyone,
>
> I'm trying to understand why I cannot use the annotated style services
> on JBoss AS 7.0.2. In particular, during the deployment I get an
> exception
>
> WELD-001408 Unsatisfied dependencies for type [BayeuxServer] with
> qualifiers [@Default] at injection point [[field] @Inject private
> org.test.cometd.service.TestService.server
>
> The problem seems to be that the BayeuxServer is not a bean and cannot
> be instantiated by the CDI.
> How can I work around this issue? I thought about adding a beans.xml
> file to the CometD jar libraries, but I don't think is the right way
> to fix it.

I think you should use a Provider or a @Produces method.
But this leaves open the question of how you export the
BayeuxServerImpl instance created by CDI to the ServletContext.

Not a big fan of CDI, but I'll take a look in detail in the next days.

Simon
--
http://cometd.org
http://intalio.com
http://bordet.blogspot.com
----
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz

Luca Merolla

unread,
Dec 5, 2011, 2:38:41 PM12/5/11
to cometd-users
On Dec 5, 6:29 pm, Simone Bordet <sbor...@intalio.com> wrote:
> Hi,
>
>
>
>
>
>
>
>
>
> On Mon, Dec 5, 2011 at 14:59, Luca Merolla <luca.mero...@gmail.com> wrote:
> > Hello everyone,
>
> > I'm trying to understand why I cannot use the annotated style services
> > on JBoss AS 7.0.2. In particular, during the deployment I get an
> > exception
>
> > WELD-001408 Unsatisfied dependencies for type [BayeuxServer] with
> > qualifiers [@Default] at injection point [[field] @Inject private
> > org.test.cometd.service.TestService.server
>
> > The problem seems to be that the BayeuxServer is not a bean and cannot
> > be instantiated by the CDI.
> > How can I work around this issue? I thought about adding a beans.xml
> > file to the CometD jar libraries, but I don't think is the right way
> > to fix it.
>
> I think you should use a Provider or a @Produces method.
> But this leaves open the question of how you export the
> BayeuxServerImpl instance created by CDI to the ServletContext.
>
> Not a big fan of CDI, but I'll take a look in detail in the next days.
>
> Simon
> --http://cometd.orghttp://intalio.comhttp://bordet.blogspot.com

> ----
> Finally, no matter how good the architecture and design are,
> to deliver bug-free software with optimal performance and reliability,
> the implementation technique must be flawless.   Victoria Livschitz

Hi Simone,

I have solved using @Alternative annotation, but for doing so I had to
extend the BayeuxServerImpl class.
@Alternative
public class InjectableBayeuxServer extends BayeuxServerImpl {
}

In alternative it has been suggested me to use the Producer. Something
like that:
public class BSP {
@ApplicationScoped
public BayeuxServer produceServer() {
return new BayeuxServerImpl();
}
}

I haven't tried yet the Producer, but I'll let you know if this
solution works too.

Luca

Luca Merolla

unread,
Dec 6, 2011, 11:37:23 AM12/6/11
to cometd-users

Hi,

I have tested also with the Producer Class and I can confirm it works.

LM

Simone Bordet

unread,
Dec 6, 2011, 12:52:06 PM12/6/11
to cometd...@googlegroups.com
Hi,

On Tue, Dec 6, 2011 at 17:37, Luca Merolla <luca.m...@gmail.com> wrote:
> I have tested also with the Producer Class and I can confirm it works.

How, exactly ? Can you post a snippet ?

How do you export the BayeuxServer instance created by the Provider to
the ServletContext ?

Matthieu Heimer

unread,
Dec 29, 2011, 3:09:09 PM12/29/11
to cometd-users
Same error when using GlassFish. To reproduce the error create a Java
EE 6 / Servlet 3.0 project and enable CDI. To enable CDI you create a
beans.xml file in WEB-INF with:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>

After enabling CDI, a:
@javax.inject.Inject private BayeuxServer bayeux;
will fail because CDI/Weld doesn't have enough information to figure
out how to satisfy the BayeuxServer dependency or what it's life-cycle
would be (annotations are missing).

The work around is to add a producer in your classpath. Here is mine:
(note that @ApplicationScoped roughly translates to ServletContext in
a web app)

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.server.BayeuxServerImpl;

public class BayeuxServerProducer {

@Produces @ApplicationScoped
public BayeuxServer produceServer() {
return new BayeuxServerImpl();
}
}

On Dec 6, 11:52 am, Simone Bordet <sbor...@intalio.com> wrote:
> Hi,
>
> On Tue, Dec 6, 2011 at 17:37, Luca Merolla <luca.mero...@gmail.com> wrote:
> > I have tested also with the Producer Class and I can confirm it works.
>
> How, exactly ? Can you post a snippet ?
>
> How do you export the BayeuxServer instance created by the Provider to
> the ServletContext ?
>
> Simon
> --http://cometd.orghttp://intalio.comhttp://bordet.blogspot.com

Simone Bordet

unread,
Dec 29, 2011, 3:22:05 PM12/29/11
to cometd...@googlegroups.com
Hi,

I am not sure of where @ApplicationScoped is supposed to store beans,
but I doubt it will export it to the ServletContext of a webapp under
the key "org.cometd.bayeux", which is what needs to be done.

So when the CometdServlet starts up, it will create another instance
of BayeuxServer, and the one created by CDI will never be used.

Matthieu Heimer

unread,
Dec 29, 2011, 6:24:19 PM12/29/11
to cometd-users
Not exactly....

With CDI enabled (beans.xml present) all uses of @Inject will be
validated for correctness. Currently cometd does not use @Inject in a
CDI compatible way. I don't think the producer I outlined will ever be
used at runtime except to validate that CDI/Weld *could* satisfy the
dependence if called on to do so.

The ServerAnnotationProcessor should still be injecting the
@javax.inject.Inject private BayeuxServer bayeux; field and so you
still only get one instance of a BayeuxServer. (Everything seems to
work and if you add println statements to the producer it doesn't seem
to be called)

Since CDI is a major Java EE 6 component cometd should be compatible
with CDI enabled applications.

The first (easy) option to fix cometd:
Don't use javax.inject.Inject. There are already cometd proprietary
annotations like org.cometd.java.annotation.Session, just make
org.cometd.java.annotation.Inject or
org.cometd.java.annotation.Server.

The second option:
Rewrite cometd-java-annotations to use CDI.

Option one could always be a stop-gap on the way to option two, for
example JSF 2.0 has CDI-like annotations that can be used when you
deploy JSF 2.0 apps to a 2.5 Servlet container but when you deploy to
a Servlet 3.0 container you would typically develop to the CDI
annotations.

-Matt

Simone Bordet

unread,
Dec 30, 2011, 8:35:43 AM12/30/11
to cometd...@googlegroups.com
Hi,

On Fri, Dec 30, 2011 at 00:24, Matthieu Heimer <matt....@gmail.com> wrote:
> Not exactly....
>
> With CDI enabled (beans.xml present) all uses of @Inject will be
> validated for correctness. Currently cometd does not use @Inject in a
> CDI compatible way.

Why not ?
Not sure what do you mean by "CDI compatible way"; the semantic of
@Inject is specified by JSR 330, and does not vary whether or not it
runs in a CDI container.

The goal is to make the DI container to create the services instances,
and the pass those instances through ServerAnnotationProcessor (which
also can be created by the DI container) for the CometD-specific
annotations.
Note that all this is already doable using Spring, which is a JSR 330
DI container, and has facilities for interact with the servlet API.

> I don't think the producer I outlined will ever be
> used at runtime except to validate that CDI/Weld *could* satisfy the
> dependence if called on to do so.

Uh, I will be extremely surprised by this: a producer that does not
produce even if there is a dependency to be resolved ?
It seems to me more a Weld requirement/bug rather than a CDI problem.

> The ServerAnnotationProcessor should still be injecting the
> @javax.inject.Inject private BayeuxServer bayeux; field and so you
> still only get one instance of a BayeuxServer. (Everything seems to
> work and if you add println statements to the producer it doesn't seem
> to be called)

Then I am doubting that CDI is used in the correct way, if it is not
the producer of BayeuxServer.
Who then creates the BayeuxServer instance that is then injected ?

> Since CDI is a major Java EE 6 component cometd should be compatible
> with CDI enabled applications.

Absolutely agree, but I'd like to see a specific failure test case.

> The first (easy) option to fix cometd:
> Don't use javax.inject.Inject. There are already cometd proprietary
> annotations like org.cometd.java.annotation.Session, just make
> org.cometd.java.annotation.Inject or
> org.cometd.java.annotation.Server.

-1.

What's the point of having a different annotation for doing the same thing ?
For the record, @Inject works nicely in Spring, which supports JSR
330, and in Guice (which has other problems, but not on @Inject), so I
am wondering why Weld has problems (because CDI must be a superset of
JSR 330).
I am still not sure that CDI really has problems, but I have not had
time yet to investigate myself.

> The second option:
> Rewrite cometd-java-annotations to use CDI.

-1.

CometD is used in other environments like mobile and standalone, and
we cannot depend on CDI; and even if CDI could be ported to mobile and
standalone, I see no strong reason to depend on it because we do not
need all the baggage that CDI brings in: CDI limitations should be
just worked around to achieve interoperability.

Having said that, would it be possible to have a simple complete
buildable project that shows that CDI / CometD are not playing well
together ?

Luca Merolla

unread,
May 15, 2012, 7:25:31 AM5/15/12
to cometd...@googlegroups.com
Hi Simone,

I don't know if you are still looking for that information. Anyway, here it is the Produce class:

public class BayeuxServerProducer {
@ApplicationScoped
public BayeuxServer produceServer() {
return new BayeuxServerImpl();
}
}

And in the CometD annotated service I just use

@javax.inject.Inject
private BayeuxServer server;

and the bayeux server is injected. It works on Jboss AS 7.x

Luca

Simone Bordet

unread,
May 15, 2012, 9:08:11 AM5/15/12
to cometd...@googlegroups.com
Hi,

On Tue, May 15, 2012 at 1:25 PM, Luca Merolla <luca.m...@gmail.com> wrote:
> Hi Simone,
>
> I don't know if you are still looking for that information. Anyway, here it
> is the Produce class:
>
> public class BayeuxServerProducer {
> @ApplicationScoped
> public BayeuxServer produceServer() {
> return new BayeuxServerImpl();
> }
> }

That is not enough.
We need the BayeuxServer to be exported to the ServletContext, which
this code alone does not do.

> And in the CometD annotated service I just use
>
> @javax.inject.Inject
> private BayeuxServer server;
>
> and the bayeux server is injected. It works on Jboss AS 7.x

You're probably running with 2 BayeuxServer instances, and I have
doubts it works properly...
For example, sessions will be held by the default instance, and you'll
inject the CDI instance.

If you have solved this problem, I am interested to know how.
Reply all
Reply to author
Forward
0 new messages