On Wed, Jun 29, 2011 at 10:43 PM, David Blevins <[email protected]> wrote: > On Jun 27, 2011, at 1:44 PM, kubamarchwicki wrote: > >> Here is my issue with OpenEJB. I'm note sure if what I'm trying to do is not >> possible or I'm doing something wrong. > > Saw your article and I don't think you're doing anything "wrong". Maybe the > existing set of features don't fully cover what you're trying to do -- or > maybe they do, but not in a convenient way. Either way, most of the existing > features came from user requests, so hopefully we can mine some gems from > your experience. > >> I use OpenEJB only for testing - embedded container. In the application I >> have multiple beans implementing same business interface, one main - with >> logic, few other in tests. What I'm looking for is possibility to (after >> bootstrapping container) override wired dependencies with the testing >> implementation. > > I'd like to spend some time attempting to do the things you describe -- walk > in your shoes, so to speak. Might be a day or two before I can do that. In > the meantime, can you take a look at this technique. It's how we write our > internal tests and is a big influence on Arquillian -- OpenEJB was a pretty > critical part of Arquillian when they were first getting it going. > > http://people.apache.org/~dblevins/application-composer/ > http://people.apache.org/~dblevins/application-composer.zip > > This is the main guy to look at: > > http://people.apache.org/~dblevins/application-composer/src/test/java/org/superbiz/composed/MoviesTest.java > > Basically with this approach there is zero classpath scanning. The only > thing built is what you give OpenEJB directly, regardless of what is floating > around in your classpath. It's also not really integration testing as the > idea is that you isolate the component (or two) you want to test and just > test that small controlled number of components. > > Mixing the worlds of fully integration testing and doing this more true unit > testing is certainly something I've thought of. Making small adjustments to > a large app is not yet as easy as it should be -- the alternative xml > approach is only so useful. > > One thought that I've had is to maybe come up with some hybrid. Some sort of > visitor pattern where, like you mention, the test case can make programmatic > changes to the application before it is deployed. > > Before we actually start building anything, our "deployment" process looks > like this: > > 1 scan for apps in the classpath > 2 read in descriptors > 3 scan for @Stateful, @Singleton, @Stateless, @MessageDriven > 4 process annotations for known components (the above, plus those in xml) > 5 validating app compliance > 6 resolving resource references > 7 resolving ejb references > 8 turning the descriptor tree into Info objects for final assembly > 9 final validation check > > Between before and after step 4 would be prime places for some developer > hooks. Before 4 you could swap out the implementations of components. After > 4 you could change any part of the metadata for an app regardless if it came > from annotations or xml -- after 4 we have pulled all the annotation data out > and essentially put the data in the objects we use to represent the > descriptor. > > One thought as to how to offer such hooks might be to do something like the > ApplicationComposer but instead of @Module methods that produce (return) > various things like EjbJar or SessionBean or PersistenceUnit, we instead have > methods that take them as arguments (basically visitor methods). Something > like: > > @PreProcess > public void anymethodName(EjbJar ejbJar) { > // do anything you want to the app before we do step 4 > } > > @PostProcess > public void anymethodName(EjbJar ejbJar) { > // do anything you want to the app after we do step 4 > } > This is a pretty neat idea! > > -David > >> How I understand OpenEJB lifecycle, first ejb-jar.xml is evaluated. After >> that - class path discovery is performed. In either cases it doesn't work >> for me. When I put something like this in ejb-jar.xml a NullPointer is >> thrown (MethodController is my business service, >> AnotherTestingDisplayingService is a testing mockup) >> <session> >> <ejb-name>MethodController</ejb-name> >> <ejb-ref> >> >> <ejb-ref-name>pl.marchwicki.ejb.controllers.MethodController/displayingService</ejb-ref-name> >> >> <remote>pl.marchwicki.ejb.view.DisplayingServiceLocal</remote> >> <ejb-link>AnotherTestingDisplayingService</ejb-link> >> <injection-target> >> >> <injection-target-class>pl.marchwicki.ejb.controllers.MethodController</injection-target-class> >> >> <injection-target-name>displayingService</injection-target-name> >> </injection-target> >> </ejb-ref> >> >> Sounds reasonable, MethodController is not yet present in context. >> >> On the other hand, when I fully define MethodController in ejb-jar.xml (like >> this) >> <session id="MethodController"> >> <ejb-name>MethodController</ejb-name> >> <mapped-name></mapped-name> >> >> <business-local>pl.marchwicki.ejb.controllers.MethodControllerLocal</business-local> >> >> <ejb-class>pl.marchwicki.ejb.controllers.MethodController</ejb-class> >> <session-type>Stateless</session-type> >> <transaction-type>Container</transaction-type> >> <ejb-ref> >> >> <ejb-ref-name>pl.marchwicki.ejb.controllers.MethodController/displayingService</ejb-ref-name> >> >> <remote>pl.marchwicki.ejb.view.DisplayingServiceLocal</remote> >> <ejb-link>AnotherTestingDisplayingService</ejb-link> >> <injection-target> >> >> <injection-target-class>pl.marchwicki.ejb.controllers.MethodController</injection-target-class> >> >> <injection-target-name>displayingService</injection-target-name> >> </injection-target> >> </ejb-ref> >> <ejb-ref> >> >> <ejb-ref-name>pl.marchwicki.ejb.controllers.MethodController/calculatingService</ejb-ref-name> >> >> <remote>pl.marchwicki.ejb.business.CalculatingServiceLocal</remote> >> <injection-target> >> >> <injection-target-class>pl.marchwicki.ejb.controllers.MethodController</injection-target-class> >> >> <injection-target-name>calculatingService</injection-target-name> >> </injection-target> >> </ejb-ref> >> </session> >> >> I get javax.naming.NameAlreadyBoundException when classpath discovery is >> performed. >> Either way my mocking doesn't work. >> >> Similar problem happens when multiple ears are collapsed into single >> classpath.ear (on tests). When multiple implementations of same business >> interface are present across different ears, there is not way in OpenEJB to >> manually pick up desired implementation. >> >> My question is - am I doing something wrong or I'm trying to 'beat the game' >> and doing things which OpenEJB wasn't designed for. >> >> The code for this example is on my github >> (https://github.com/kubamarchwicki/ejb-testing) if some reference is needed. >> >> many thanks >> Jakub >> >> -- >> View this message in context: >> http://openejb.979440.n4.nabble.com/override-annotation-based-configuration-with-ejb-jar-xml-tp3628804p3628804.html >> Sent from the OpenEJB User mailing list archive at Nabble.com. > >
-- Karan Singh Malhi twitter.com/KaranSinghMalhi
