I got a request - come help me with these failing unit tests. The cause? The dreaded Null Pointer Exception. A member variable wasn't initialised in the constructor, but in in an init() method annotated with javax.annotation.PostConstruct. The inital impulse was to call init in the tests, but this would have led to other problems as other member variables would try to acquire container resources via JNDI (and a ServiceLocater pattern), and since this is a unit test we are mocking those dependencies. The better idea is to factor the initialisation of the attributes that are needed all the time into the constructor (which solved the NPE problem), and those attributes that are holding container resources into the @PostConstruct method since the container will honour the annotation; whereas in the unit test we can setup up the dependencies with mocks. A nice little trick but one that's very powerful.
A better approach is of course to use a DI framework, but that still doesn't get around a bad design. Separating container concerns into a @PostConstruct method (and using constructor injection perhaps) makes the class more testable with the tests taking the responsibility for being the container.
Showing posts with label EJB. Show all posts
Showing posts with label EJB. Show all posts
Wednesday, October 20, 2010
Tuesday, August 24, 2010
Ambigous documentation and my BMT pain
For the project I'm working on I have an EJB that's operating in a Bean Managed Transaction or BMT. One of the beauties of a BMT is that you can extend your transaction timeout to be longer than the default JTA timeout value for long running DB operations. Sometimes you just have to shift a ton of data around with a minimal amount of domain logic and a BMT suits this nicely.
However I feel there is some ambiguity in the UserTransaction setTransactionTimeout method docs that has caused me a lot of grief.
Modify the timeout value that is associated with transactions started by the current thread with the begin method.
This leaves two possibilities in my mind:
The gotcha is that while both are reasonable interpretations of the API docs, only the second works for me (caveat: I've only tested this on Oracle's OC4J as part of Fusion 10G; other app servers may behave differently).
Needless to say that I took the first option then wondered why I was getting timeouts consistent with the transaction timeout being the value of the server's JTA timeout value, not what I set on the transaction (after starting it). So after a lot of digging, and checking that the container was behaving itself and not starting a transaction when it wasn't, and making sure I was getting access to the correct resources, option two hit me like a brick. Flipping two lines of code, and it all worked perfectly.
When dealing with API doc ambiguities, the thought that "hey I'm reading this wrong" doesn't often enter your head until the very end, when there's blood on the desk from the crack in your skull.
Very annoying!
However I feel there is some ambiguity in the UserTransaction setTransactionTimeout method docs that has caused me a lot of grief.
Modify the timeout value that is associated with transactions started by the current thread with the begin method.
This leaves two possibilities in my mind:
- Start a transaction, and set it's timeout.
- Set the timeout for all transactions started by the UT, then begin transactions when you want to.
The gotcha is that while both are reasonable interpretations of the API docs, only the second works for me (caveat: I've only tested this on Oracle's OC4J as part of Fusion 10G; other app servers may behave differently).
Needless to say that I took the first option then wondered why I was getting timeouts consistent with the transaction timeout being the value of the server's JTA timeout value, not what I set on the transaction (after starting it). So after a lot of digging, and checking that the container was behaving itself and not starting a transaction when it wasn't, and making sure I was getting access to the correct resources, option two hit me like a brick. Flipping two lines of code, and it all worked perfectly.
When dealing with API doc ambiguities, the thought that "hey I'm reading this wrong" doesn't often enter your head until the very end, when there's blood on the desk from the crack in your skull.
Very annoying!
Wednesday, August 4, 2010
Love that injection
The EJB 3 specification greatly simplified the world of EJBs by borrowing ideas from the Spring camp, the most powerful of which is the idea of POJOs coupled with annotations if you are living in a >= Java 5 world.
I've been playing around with Spring 3 lately, and I'm starting to find the value again in having an XML configuration/deployment descriptor within my EJB work. In all the annotation hype for EJB3, I wonder if we haven't lost sight of the flexibility that text based configuration can bring us in regards to injecting resources into our beans. Sure XML can be tedious but with the amount of great XML tooling available, is that a good reason not to use the XML options? We can get autocomplete, validation and syntax highlighting out of the box. I personally use Eclipse but other IDEs have the capability. Unfortunately we can see the annotation vs XML debate spiral mostly into personal preference. Sure having the configuration for an external resource in the code is great - if it rarely changes. If you have constant change (say on a per environment basis) perhaps a text based approach is better. Text based configuration is perhaps easier for us to create scenarios for our testing.
I've recently had the problem where I've had to change the JDBC driver for a DataSource due to environment issues. The ORM work is done by JPA. The annotation on the EntityManager points to a particular persistence unit. Great, because that's hardly ever going to change. If we do change the persistence unit, it may have an impact on the rest of the codes behaviour so going into the source is worth it. However there are two different persistence unit configurations - one for production (in the container) and the other for unit testing (out of the container). These are configured in the persistence.xml, and the code is oblivious. Just as it should be.
Unfortunately the wheel is reinvented too many times. Are we really doing anything different by the fact that we need configurable code? I admire an engineers ability to solve the problem. That's what we get paid for. Maybe bundle a properties file in the JAR, find it on the classpath (and load it). Maybe there is a property that we can then use to do a JNDI lookup to get a handle/reference to a DataSource. But why would you do that when you have the <resource-ref> tag available to you in the deployment descriptor.
On a technical note, there is an unfortunate pitfall to using deployment descriptor features like a <resource-ref> that can frustrate a developer and make him/her reach for their own custom solution. Say within a bean you have
My current thinking at the moment is about how we can leverage technology like EJB3 and Spring to cleanly and efficiently solve clients needs. The first onus falls on guys like me, the developers to know our material. The second is that if we don't know the answer to a question (for example how can I change the JNDI location of my injected DataSource at build time) then we need to do our homework. I'm just as much guilty as the next guy for failing to do this. Doesn't mean I shouldn't get a rap over the knuckles for it.
I've been playing around with Spring 3 lately, and I'm starting to find the value again in having an XML configuration/deployment descriptor within my EJB work. In all the annotation hype for EJB3, I wonder if we haven't lost sight of the flexibility that text based configuration can bring us in regards to injecting resources into our beans. Sure XML can be tedious but with the amount of great XML tooling available, is that a good reason not to use the XML options? We can get autocomplete, validation and syntax highlighting out of the box. I personally use Eclipse but other IDEs have the capability. Unfortunately we can see the annotation vs XML debate spiral mostly into personal preference. Sure having the configuration for an external resource in the code is great - if it rarely changes. If you have constant change (say on a per environment basis) perhaps a text based approach is better. Text based configuration is perhaps easier for us to create scenarios for our testing.
I've recently had the problem where I've had to change the JDBC driver for a DataSource due to environment issues. The ORM work is done by JPA. The annotation on the EntityManager points to a particular persistence unit. Great, because that's hardly ever going to change. If we do change the persistence unit, it may have an impact on the rest of the codes behaviour so going into the source is worth it. However there are two different persistence unit configurations - one for production (in the container) and the other for unit testing (out of the container). These are configured in the persistence.xml, and the code is oblivious. Just as it should be.
Unfortunately the wheel is reinvented too many times. Are we really doing anything different by the fact that we need configurable code? I admire an engineers ability to solve the problem. That's what we get paid for. Maybe bundle a properties file in the JAR, find it on the classpath (and load it). Maybe there is a property that we can then use to do a JNDI lookup to get a handle/reference to a DataSource. But why would you do that when you have the <resource-ref> tag available to you in the deployment descriptor.
The beauty of course is that ${propertyName} can be substituted in by your build framework. The Ant <expandproperties> filter is great for this. You're also within the spirit of the framework, and hopefully your code is more maintainable, with no custom loading and no lookups. Of course you may have this requirement across multiple beans so you may have to replicate your custom code across those beans. Ugly!! If you're worried about people not being able to trace what's going on, place a comment over the class attribute "This is configured in the deployment descriptor". That of course is a no brainer because good developers always document their code for future readers ;).
<session>
<ejb-name>SomeBean</ejb-name>
<resource-ref>
<res-ref-name>${propertyName}</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<injection-target>
<injection-target-class>org.foo.SomeBean
</injection-target-class>
<injection-target-name>dataSource
</injection-target-name>
</injection-target>
</resource-ref>
</session>
On a technical note, there is an unfortunate pitfall to using deployment descriptor features like a <resource-ref> that can frustrate a developer and make him/her reach for their own custom solution. Say within a bean you have
What you're doing is essentially two things
@Resource(name="jdbc/SomeDS")
private javax.sql.DataSource dataSource;
- Requesting a DataSource object at the JNDI location jdbc/SomeDS
- Requesting that the reference be assigned to the class attribute dataSource
My current thinking at the moment is about how we can leverage technology like EJB3 and Spring to cleanly and efficiently solve clients needs. The first onus falls on guys like me, the developers to know our material. The second is that if we don't know the answer to a question (for example how can I change the JNDI location of my injected DataSource at build time) then we need to do our homework. I'm just as much guilty as the next guy for failing to do this. Doesn't mean I shouldn't get a rap over the knuckles for it.
Subscribe to:
Posts (Atom)