On Wed, Jun 29, 2011 at 10:43 PM, David Blevins <david.blev...@gmail.com> 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

Reply via email to