Another new feature that’s being discussed in the EJB 3.1 expert group is the of a no-interface view for session beans. This means that your bean classes do not have to implement and publish an interface.
@Stateless public class StockTrader { public void buy(Stock stock, int quantity) {...} public void sell(Stock stock, int quantity) {...} }
The default case, with no additional metadata would publish the StockTrader class as a local view on this stateless bean, so, a client would either receive injected or jndi looked up referenced to the StockTrader class.
@ EJB StockTrader trade; StockTrader trade = (StockTrader)jndi.lookup("StockTrader/local");
The idea behind this new feature is to reduce the number of artifacts needed in simple applications.
Callback/injection issues
The side effect of this new feature is what do we do about public callback and dependency injection methods?
- Don’t allow callback methods to be public. Not having callback methods private does make it harder to unit test these type of methods. The SessionSynchronization interface also poses a problem for this approach. Do we not allow SessionSynchronization interface to be placed on no-interface view SFSBs?
- Don’t allow DI setter methods to be public. You have the same unit testing issue with this approach as #1. Also, setter methods would seem very useful as a business method for SFSB and Singleton beans.
- Throw an exception if a public callback method is invoked at runtime.
- Throw an exception if a public setter method is invoked at runtime. Again, setter methods as part of the business interface would be very useful for SFSBs and singleton beans, but weird for SLSBs. maybe only throw an exception for public setters on SLSBs?
- Allow callback methods to be public and callable from the no-interface view
- Allow DI setter methods to be public and callable from the no-interface view. Although very useful for SFSBs and Singletons, would have weird consequences for SLSBs.
Feedback???
Remote no-interface views?
Should we allow remotable no-interface views? IMO, this is bad practice as you making business logic available to a possible untrusted client. Yeah, I know we had this feature in JBoss AOP Remoting, but maybe it is a bad idea? Or should we just let the app developer decide if it is a good idea or not? Web services already allows a no-interface view, but this view is usually translated to WSDL which is then compiled to a generated Java interface anyways. A remote view would still be using the business object.
I’m begging for feedback
Any feedback is extremely useful, even a +1, -1 comment.
Sep 24, 2007 @ 12:40:21
This means that your bean classes do not have to implement and publish an interface.
+1, it’s important to reduce artifacts in simple application
Callback/injection issues
I would prefer non public method for callback. I’d like package limited access, a good design of tests would consider testing of default access method if needed.
Regarding DI setters and their usefulness in singleton I’m perfectly agree. Probably the best choice in this case would be an exception when called runtime. If you want an uniform behavior, throwing exceptions would be the choice.
Remote no-interface views?
IMO too it’s a bad practice.
Sep 24, 2007 @ 14:27:00
This means that your bean classes do not have to implement and publish an interface.
-1, although it may make it easier for simpler applications to not require an interface, you are creating an ‘exception’ to the standard/rule. This causes less consistency and more complexity.
The more ‘exceptions’ to the common rule, the more complex, the less consistent, the more bloated the standard becomes.
Sep 24, 2007 @ 15:03:49
I use EJB-3 more and more like a medium-weight dependency-injection framework. An enforced interface sometimes reduce the clarity of the code. Thus, I like the idea of a no-interface view.
I think it is ok to have callback methods that are private. This states that only the container is allowed to access them. It makes testing a little bit harder but in our last project we wrote a small utility that emulated the container in a test.
If the callback methods are not private they should be callable from everyone who has access. I would be surprised if I encounter an exception.
If you introduce a no-interface view it should also be possible to annotate methods to be remotely callable. The default behavior should only give local access.
Sep 24, 2007 @ 15:39:35
I think it will make sense for SLSB that only serve as Webservice endpoint.
Sep 24, 2007 @ 21:09:28
No-interface view
+1
Consider Seam or JSR-299/Web Beans spec. If one wants to create EJB3 WebBean, they are currently enforced to create an interface, but usually this interface is never used.
Callbacks, DI setters
To my way of thinking, it’d be good idea to handle both callback methods and DI setters here in the same way, or at least the most uniform way that makes sense. So, for instance, allow those methods to be public (since they can be useful for SFSBs and Singletons) and only throw an exception for public setters on SLSBs.
Remote no-interface views
I agree, it’s a bad practice.
Sep 24, 2007 @ 21:38:38
This means that your bean classes do not have to implement and publish an interface.
-1 I do think it is a nice idea to reduce artifacts for simple applications but I’d rather have to deal with them then breaking the requirement for interfaces. After all “simple applications” are the audience you’re targeting with this “enhancement” but by definition this type does not have a whole lot of beans and interfaces anyways. So the “overhead” that you’ll be able to remove is not that big.
But on the other hand for medium and large applications removing the requirement for interfaces can result in quite some chaos.
Sep 25, 2007 @ 00:39:46
-1 on non-required interfaces, whether local or remote. It’s a straightforward and simple rule that covers all cases – each implementation class must implement at least one Local or Remote interface.
S,
ALR
Sep 25, 2007 @ 05:27:26
Of course local interfaces should not be required. This was a bad decision to put back in the EJB 3.0 spec – remember it wasn’t there in an early draft. Every class _already_ implements several interfaces even if you don’t declare it explicitly. One of them is the interface that is represented by its public methods (others are the protected and private interfaces). Do not force me to extract this interface into a separate file.
Sep 25, 2007 @ 10:43:30
Local no-interface view?
+1, Definitely. Keep it simple (or simpler).
Remote no-interface views?
+1 and let the developer decide. The simplest ‘Hello World’ local/remote EJB should be available to a developer with a minimum of effort. Anything we do to make the simplest applications easier will make more people use this spec.
Sep 25, 2007 @ 14:51:09
Don’t allow it; it promotes bad design practices. Programming to interfaces is a key software development pattern crucial to testing and maintenance of code. I realize it saves some time, but how much really? It probably simplifies the code too, but I would have serious concerns about the competency of a programmer that found interfaces confusing.
Sep 25, 2007 @ 15:33:24
-1 for remote no-interface. As you may have been implying: the generated WSDL is the “interface” for web services. It seems like a bad idea to put that behavior into the spec. If an implementation wants to allow this shortcut, fine. In fact, it’s great. However the spec should be more conservative, and promote a more “standard” practice.
Even for simple applications, is defining an interface that difficult? Any modern IDE can help with that.
Sep 26, 2007 @ 05:51:24
i would appreciate this very much. The using should be allowed not imposed as it is now. The designer may decide when to and not use it.
Sep 26, 2007 @ 07:25:36
-1 on optional interfaces, but allow a single interface to be both @Local and @Remote at the same time by adding a simple way to choose the interface type for injected dependencies, for example @EJB(type = InterfaceType.LOCAL|REMOTE). A possible further enhancement would be the possibility to override local/remote visibility for each business method individually by applying @Local/@Remote again.
Sep 26, 2007 @ 09:23:28
Why not provide annotation of classes/methods : @Remote and @Local?
If the EJB class implements an I/face, the I/face can be annotated and each method in it will ‘have’ that annotation. Interfaces should be allowed to have both annotations.
If the class is annotated, all get/set methods will be exposed.
If methods are annotated, this will override the Class level annotation.
Something akin to @Transient should be added – @Container/@Hidden (?) – which will restrict these.
My 2c.
Sep 26, 2007 @ 13:21:49
I like Mike’s comment – Allow a single interface to allow @Local and @Remote (@Webservice, others?). One interface, with method-level adjustments to ‘visibility’, for all ways the actual implementation(s) could be exposed.
Instead of saying ‘no interface for this scenario, but allow it for others’, improve by simply having one interface file for all ways to expose actual implementations (instead of multiple interfaces).
Sep 27, 2007 @ 01:32:41
I think interfaceless is good. there are many times when the interface is just filler. I guess it means that everything will have to be done by dynamic subclass (which is of course badmojo), cglib, javassist or whatever…but many times I’m just looking for transactions.. . I’m more interested in turning pooling off though. Pooling ala SLSBs is totally lame/pointless/sucky.
@ISimplyWantATransactionalBeanWithNoFluff(pool=off) //which should be default for TJB’s (TransactionalJavaBeans)
public class MyBean {
@TransactionAttribute(TransType.REQUIRES_NEW)
public void sendBillHatFromCheetah() {
// …
}
}
public class MyOtherBean {
@TJB
MyBean bean;
…
bean.sendBillHatFromCheetah();
…
}
These “simpleBeans” or (TransactionalJavaBean) might be a subclass proxying to a container with the so-called “Bridge” pattern. Or they might be directly injected *gasp* without the “container” as subclasses with the @TX stuff or whatever injected. Really I’d just like a lot less silly shit when all I want to do is demarcate transactions, manage @EntityMangager (aka the session) etc. Most “Enterprise” applications don’t really need a whole lot more than IoC, TX management and Session management.
As for web services, I never got why SOAP is such a special transport. That is just invocation, why does it need special treatment? Maybe I have annotations saying @InvoationLayers(SOAP,REST,RMI,IIOP,JSON,WHATEVER) or maybe that stays outside. I agree that a special web service interface is the lamest thing ever.
-Andy
Sep 27, 2007 @ 13:41:29
Hi,
+1
I realy like the Idea not having to implement te interfaces.
But an @Remote or @Local tag on a class makes sense for me.
Kind regards,
Mark
Sep 27, 2007 @ 16:19:31
+1 on optional local interface (anything public is exposed *anyway*), but -1 on optional remote interfaces.
Sep 27, 2007 @ 17:00:47
+1
Remote no-interface views?
How about:
@Stateless
public class StockTrader {
/*
* This one is local
*/
public void buySpecial(Stock, int quantity, other special parameter for local access) {}
/*
* These are remote
*/
@Remote
public void buy(Stock stock, int quantity) {…}
@Remote
public void sell(Stock stock, int quantity) {…}
}
Sep 29, 2007 @ 22:34:42
-1 optional Remote||Local interfaces.
Programming to interfaces is a good practice and should be encouraged as it allow good patterns and clean design.
I do agree with Mike idea of making both @Remote and @Local a single interface (one single business interface) and allow them to be overridden at method level.
Although Session Beans are a mean to implement web services they still should be treated separately and annotations like “@InvoationLayers(SOAP,REST,RMI,IIOP,JSON,WHATEVER)” like suggested by Andy IMHO are not very consistent with the actual programming model at least.
One last thing please more aop.
Daoud AbdelMonem Faleh.
Sep 30, 2007 @ 09:31:15
I like the previous comment but would like it more with:
@Stateless
public class StockTrader {
public void create() {} //call back
public String foo() {} //nothing special
@Local public void bar(){} //local
@Remote public void trudy(){} //Remote
}
the call back if not called “void create()” could then have a @create annotation.
a “@IsManaged private Boolean isManaged = false;” could be set to true by the container if the container is taking care of the bean.
alex
May 23, 2008 @ 01:44:07
+1 for optional local interface. Having to code a local view and a remote view is tedious, and having the flexibility to switch seamlessly between local and remote versions of the bean is beneficial.
-1 for optional remote interface. Remote clients should program against an interface of my bean, not my bean itself. Not to mention, private/public access is a stupid way to define which methods are accessible to remote “users” of my bean. That’s why interfaces exist. To decouple systems, and allow concrete agreements between users and implementations. Interfaces allow me to remain conscious of the design of my application, and how outside users view it. Also, did someone say unit testing?
While Mike’s idea of combining the interfaces is quite brilliant, I say don’t bother. Internally, I don’t mind programming against my bean directly. Again, that’s not what interfaces are for. But remotely… mmhmm! Interfaces!