You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by Laird Nelson <lj...@gmail.com> on 2009/08/12 17:18:03 UTC

Preventing deployment under a given interface

I feel sheepish even asking this question because it seems like it should be
absolutely straightforward, and yet I am too slow to see it.

I have an interface, DAO.java.  It is not annotated in any way.  For the
purposes of this email it doesn't matter what method signatures are in it.

I have another interface, Foo.java.  It extends DAO.  It is not annotated in
any way.  Again, the method signatures don't matter.

Finally, I have a stateless session bean, Bar.java.  Bar implements Foo (and
by extension implements DAO).  It is annotated with @Stateless(name = "Bar")
and @Remote(Foo.class).  It properly implements all methods it's required
to.

When I run my unit tests with OpenEJB, Bar is deployed "under" the
interfaces Foo and DAO.  How can I prevent it from being deployed under
DAO?  That is, I don't want it to be possible for some other EJB somewhere
to do this:

@EJB
private DAO dao; // XXX want to prevent this

How can I do that in a specification-compliant manner?

Thanks,
Laird

Re: Preventing deployment under a given interface

Posted by Laird Nelson <lj...@gmail.com>.
On Wed, Aug 12, 2009 at 11:18 AM, Laird Nelson <lj...@gmail.com> wrote:

> I have an interface, DAO.java.  It is not annotated in any way.  For the
> purposes of this email it doesn't matter what method signatures are in it.
> I have another interface, Foo.java.  It extends DAO.  It is not annotated
> in any way.  Again, the method signatures don't matter.
> Finally, I have a stateless session bean, Bar.java.  Bar implements Foo
> (and by extension implements DAO).  It is annotated with @Stateless(name =
> "Bar") and @Remote(Foo.class).  It properly implements all methods it's
> required to.
>

To be specific, OpenEJB, running as a local server, is attempting to deploy
Bar under its remote business interface, Foo, which I want, and under its
local business interface, DAO, which I don't want, and which, to my
knowledge, I never indicated should happen.

Is this a bug in OpenEJB, or is this specification-compliant behavior?  I
thought that if you had explicitly annotated your SLSB with, say,
@Remote(SomeClassHere.class), and if you had not also explicitly annotated
it with the @Local annotation, then OpenEJB should deploy your bean under
ONLY the SomeClassHere.class interface, regardless of what other
non-annotated interfaces you might implement.

Best,
Laird

Re: Preventing deployment under a given interface

Posted by David Blevins <da...@visi.com>.
On Aug 12, 2009, at 8:18 AM, Laird Nelson wrote:

> I feel sheepish even asking this question because it seems like it  
> should be
> absolutely straightforward, and yet I am too slow to see it.
>
> I have an interface, DAO.java.  It is not annotated in any way.  For  
> the
> purposes of this email it doesn't matter what method signatures are  
> in it.
>
> I have another interface, Foo.java.  It extends DAO.  It is not  
> annotated in
> any way.  Again, the method signatures don't matter.
>
> Finally, I have a stateless session bean, Bar.java.  Bar implements  
> Foo (and
> by extension implements DAO).  It is annotated with @Stateless(name  
> = "Bar")
> and @Remote(Foo.class).  It properly implements all methods it's  
> required
> to.
>
> When I run my unit tests with OpenEJB, Bar is deployed "under" the
> interfaces Foo and DAO.  How can I prevent it from being deployed  
> under
> DAO?  That is, I don't want it to be possible for some other EJB  
> somewhere
> to do this:
>
> @EJB
> private DAO dao; // XXX want to prevent this
>
> How can I do that in a specification-compliant manner?

What you describe is not a feature we have -- I say feature as JBoss  
supports it and one or two people have asked for it.  If the Bar bean  
class does not directly implement DAO in its class or a super class,  
then it isn't (or didn't think) possible to get a reference to it via  
"@EJB DAO myDao;"

I gave this a try just to make sure I wasn't crazy (it happens :).  I  
took the simple-stateless example and extracted the CalculatorLocal  
interface into a "super" interface called Calculator.  Then I added  
another bean that attempted reference it via Calculator.

     @Stateless
     public class CalculatorImpl implements CalculatorRemote,  
CalculatorLocal {
         public int sum(int add1, int add2) {
             return add1+add2;
         }
         public int multiply(int mul1, int mul2) {
             return mul1*mul2;
         }
     }

     public interface CalculatorLocal extends Calculator {

     }

     public interface Calculator {
         int sum(int add1, int add2);
         int multiply(int mul1, int mul2);
     }


     @Stateless
     public class MyBean implements MyInterface {

         @EJB
         private Calculator calculator;

         public Calculator getCalculator() {
             return calculator;
         }
     }

When I go to run that, I get a failed deployment like so:

WARN - Unresolved ejb reference "org.superbiz.calculator.MyBean/ 
calculator" in bean "MyBean".  Will attempt resolution again at runtime.
INFO - Enterprise application "classpath.ear" loaded.
INFO - Assembling app: classpath.ear
INFO - Jndi(name=CalculatorImplLocal) --> Ejb(deployment- 
id=CalculatorImpl)
INFO - Jndi(name=CalculatorImplRemote) --> Ejb(deployment- 
id=CalculatorImpl)
INFO - Jndi(name=MyBeanLocal) --> Ejb(deployment-id=MyBean)
INFO - Created Ejb(deployment-id=MyBean, ejb-name=MyBean,  
container=Default Stateless Container)
INFO - Created Ejb(deployment-id=CalculatorImpl, ejb- 
name=CalculatorImpl, container=Default Stateless Container)
INFO - Deployed Application(path=classpath.ear)
WARN - Injection data not found in enc:  
jndiName='org.superbiz.calculator.MyBean/calculator', target=class  
org.superbiz.calculator.MyBean/calculator


Is this the scenario you are describing?

-David