You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by David Blevins <da...@gmail.com> on 2011/07/01 02:17:11 UTC

Re: override annotation based configuration with ejb-jar.xml

On Jun 30, 2011, at 12:27 PM, kubamarchwicki wrote:

> 
> Romain Manni-Bucau wrote:
>> 
>> if i remember i wrote an abstract class for testng
>> 
>> https://issues.apache.org/jira/browse/OPENEJB-1526

Check that in!  That's great.  Having not done a lot of work in TestNG I simply had no idea how to accomplish the same thing.  That looks great and we can probably refactor things internally for a little more reuse.

Side note to Jakub on the ApplicationComposer.  What we're doing internally is adding your test case to the app as a bean and deploying it.  It is effectively the same as creating an inner-class bean to drive testing.  The method-level services that beans get are not there yet (see the last section below), but 100% of the dependency injection that an EJB can get a test case can get too.  This is true of ApplicationComposer or use of the EJBContainer API (also detailed below).

And in terms of third-party frameworks offering this dependency injection and "portability" to test cases, I admit I scratch my head a little bit.  Dependency injection is Inversion of Control and Inversion of Control is already all about portability.  It is invisible by definition and the entire point is that you *don't* see or have a dependency on who is doing the injection.  Your only dependency is on the things you need injected -- your stuff.  So who really cares who is doing the injection -- the container itself or a third-party test framework that pulls the stuff from the container and puts it in.  Neither is less or more "portable" and ultimately what you can get injected boils down to what the container you are testing with supports.

The only real question of portability is in the bootstrapping process.  The EJBContainer API is currently the only spec standard bootstrapping mechanism we have and is only the start.  All vendors have no choice but to support it if they want to be a certified Java EE implementation -- full profile or web profile.  The more we as an industry adopt it, the more requirements we demand from it, the more things evolve and the more features get added back into spec.  The innovation of a few vendors get pushed back onto all the vendors and the level of portability increases.

The idea of a third-party framework that does the testing integration work for the vendor, taking on the work of creating and maintaining an adapter for each popular platform, is certainly interesting and can no doubt move a little quicker.  But I question its ability to persist over time.  It's a lot to maintain and there is no incentive for vendors to be anything but lazy.  Regardless, I applaud either approach -- any step forward is a good one.  It's beyond wonderful to see what can only be described as a testing renaissance happening in Java EE.

People typically don't test Spring components without Spring and if things were that easy in Java EE (via any means) people wouldn't dream of the Do It Yourself approach.  It all boils down to speed and convenience.  We're finally taking concrete steps down that path in Java EE.

> Romain, that looks like an absolute class! I'll give it a try and share my
> experience as a follow up to the articles I've already written. I've already
> tried with JUnit and I'm excited about the results. The test are running few
> times faster (no need to bootstrap persistence unit on every test for
> example). I must admit that's something I've been looking for.

Right.  And in trunk (OpenEJB 4.0) we've married this with the EJBContainer API which basically gives you the same "build your app" functionality without any test framework specific things.  Since it is not testing specific, you could use it in any kind of standalone app.  Small example of manually creating one little bean in a jar:

   http://svn.apache.org/repos/asf/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/OpenEjbContainerTest.java

Note that also shows injection of the class who bootstrapped the EJBContainer API.  You can actually get that without the cast to OpenEjbContainer by just calling `EJBContainer.createEJBContainer().getContext().bind("inject", this);`  Nearly all our examples in trunk have been ported to the EJBContainer API:

   http://ci.apache.org/projects/openejb/examples-generated/   (this little tool is two weeks young and still a work in progress)

Standardly that API has a couple ways to disable the classpath scan (the magic part).  You can pass String, String[], File or File[] as the value of the `javax.ejb.embeddable.modules` property of the `javax.ejb.embeddable.EJBContainer` API.

  - String, String[] = the module name(s) you want deployed.  Module name is as defined by the Java EE 6 rules: defaults to the directory or jar name sans the extension, but can be explicitly set in the related descriptor via the `<module-name>` element
  - File, File[] = the actual file paths of the modules you want deployed.

That still might get you more than you want -- allows you to identify modules, but doesn't allow you to be more specific and select individual components.  I hope at some point there is a standard way we can do that, but in the meantime we do have some extensions to the `javax.ejb.embeddable.modules`.

Alternatively, we will allow you to pass in any of the descriptor trees we understand -- these are the same as supported by ApplicationComposer.  Currently supported in 4.0.0-SNAPSHOT:
  
  - EjbJar
  - EnterpriseBean (convenience shorthand of EjbJar)
  - Application
  - Connector
  - Persistence
  - PersistenceUnit (convenience shorthand of Persistence)
  - Beans (aka cdi beans.xml, not well known yet)

Don't yet have support for collections of these things, but that will be there before final version.  With the ApplicationComposer you can just have several @Module methods and pass back any of the above, so building a larger app is easy.  Certainly passing a List<Object> as the value of "javax.ejb.embeddable.modules" will be supported.  But since there's already a Map being passed as the value of `EJBContainer.createEJBContainer`, there's no reason to cram everything into one key and instead we could just allow you to `map.put("myModule", ejbJar);`

Not supported yet as a `javax.ejb.embeddable.modules` value, but we will add before final and is something I would really like to add in EJB 3.2 as a standard part of the EJBContainer API is:

  - Class, Class[] = just give us the class(es) directly.  Skip the scrape and hand them right to us.  We'll treat them as if we "found" them on the classpath.  Nice thing is no vendor-specific objects and anyone should be able to support it.  Could be of limited use without descriptor data, but with a little clever thinking we can probably find a way to work that in.  A simple class that wraps Class[] and URL[] (the descriptors) would do the trick.  Anytime you introduce a new type on a spec level it is hard to keep people focused on keeping things simple, but we might be able to pull it off.  Getting the `javax.ejb.embeddable.EJBContainer` API in there at all was quite the feat and only possible because of the maturity of the InitialContext approach we had proven works.  Obviously a lot more is required beyond that simple API, but getting the entire industry to agree to support embedded EJB Containers is a game-changing step forward.

Summary: all of the above pertains to just plain old `javax.ejb.embeddable.EJBContainer` API which is not testing specific.  Applies to any EJB development where you simply do not want a server or would prefer to work in a plain Java SE environment.


Back in the testing world, there are more interesting things that can be done besides skipping the scrape and building apps in code.  Specifically, if EJB as an environment offers services like transactions and security that can be declared on individual methods of beans, why not let tests do the same?  Why not allow people to specify with an annotation on their test method if they need a transaction or not, or if the test should be executed as a particular role.  This is all in the experimental stage, but indicative of what we'd like to see in next.next. gen testing:

  // Run each test as a specific role and do your own pass/fail checking
  http://svn.apache.org/repos/asf/openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEjbSecurityRunTestAs.java

  // Run each test N times and have the framework do the pass/fail checking
  http://svn.apache.org/repos/asf/openejb/trunk/openejb3/container/openejb-junit/src/test/java/org/apache/openejb/junit/TestEjbSecurity.java

Obviously, this starts to really get at some of what makes integration testing hard which is dealing with combinations of factors.  EJB as a concept tries to take the complexity of several real world factors out of code (security, transactions, etc).  Unless there is some equally easy way to express these factors in tests, the complexity winds up in the testing code.  The two need to be at the same level.

Anyway, it's a huge evolving topic we're obviously very passionate about.  Hoping to use much of the above for documentation -- we need it -- and you're more than welcome to use any of it as well in your writings -- we need help there too :)


-David


Re: override annotation based configuration with ejb-jar.xml

Posted by kubamarchwicki <ku...@marchwicki.pl>.
Hi David, 
It has been a while, but the details and suggestions on running app-composer
test made my July very busy - refactoring a vast selection of OpenEJB tests
(making it run significantly faster). 
I like the idea of @PreProcess and @PostProcess - this looks like something
I'm looking for. My intention is to leverage tools like Mockito or Easymock.
I'm still not sure if that's gonna work - I hope so. At the moment I'm
building inner classes, which mock certain pits and pieces of functionality
and use them in application composer to build the context. This is not as
flexible as I'd love to - but works better in my tests that complete
classpath scanning. 
What you've shown in examples from OpenEJB 4.0 looks similar and it seems
sufficient for everything I can imagine. A little bit more verbose, but it's
not an issue (at least from my perspective). 

The other issue I was initially trying to solve, disappeared when I used
app-composer approach. In my application I have multiple implementation of
same business interface, deployed among multiple ears. During tests with
OpenEJB I have little control over what gets injected where. Now, I can
build and deploy multiple EjbJar, knowing exactly what gets wired and where. 

Honestly, after this discussion and after trying out a few things I don't
feel I need any other 'frameworks' and in terms of testing OpenEJB works
great for me. I'll be still pushing 3.1.4 version (which is one I'm
currently using) and I'm looking forward to 4.0 :-) 

Once again - many thanks
--Jakub

--
View this message in context: http://openejb.979440.n4.nabble.com/override-annotation-based-configuration-with-ejb-jar-xml-tp3628804p3699370.html
Sent from the OpenEJB User mailing list archive at Nabble.com.