Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Tuesday, December 29, 2009

@DataSourceDefinition -- A Hidden Gem from Java EE 6

In the old days, DataSources were configured -- well, they were configured in lots of different ways... That's because there was no 'one way' to do it -- in JBoss, you created an XML file that ended in '-ds.xml' and dumped it in the deploy folder... in Glassfish, you either use the admin console or muck with the domain.xml file... in WebLogic you used the web console... and this was all well and good -- until I worked with an IT guy who told me just how much of a pain in the ass it was...

Up until then, it wasn't such a big deal to me -- I set it up once, and that was that... then I ran into this guy a few jobs ago who liked to bitch and complain about how much harder it was to deploy our application than the .NET or Ruby apps he was used to... he had to deploy our data source, then he had to deploy our JMS configurations -- only then would our application work... in the other platforms, that was all built into the app (I'll have to take his word for it, since I haven't actually deployed anything in either platform)... I was a but surprised at first, and then I realized that maybe he had a point... nah, it couldn't be, he must just be having a bad day (lots of us were having bad days back then :) )...

Then I ran into Grails, which is dead simple -- you have a Groovy configuration file that has your db info in it... you even have the ability to specify different 'environments', which can change depending on how you create your archives or run your app... pretty slick...

The Gem

Well, lo and behold, we now have something that's nearly equivalent in Java EE 6 -- the @DataSourceDefinition attribute... it's a new attribute that you can put on a class that provides a standard mechanism to configure a JDBC DataSource into JNDI, and as expected, it can work with local JNDI scopes or the new global scope, meaning you can have an Environment Configuration that uses this attribute making it shareable across your server... it works like this:


import javax.annotation.sql.DataSourceDefinition;
import org.jboss.seam.envconfig.Bind;
import org.jboss.seam.envconfig.EnvironmentBinding;

@DataSourceDefinition (
className="org.apache.derby.jdbc.ClientDataSource",
name="java:global/jdbc/AppDB",
serverName="localhost",
portNumber=1527,
user="user",
password="password",
databaseName="dev-db"
)
public class Config {
...
}


As you would expect, that annotation will create a DataSource that will point to a local Derby db, and stick it into JNDI at the global address 'java:global/jdbc/AppDB', which your application, or other applications can refer to as needed... no separate deployment and no custom server-based implementation -- this code should be portable across any Java EE 6 server (including the Web Profile!)...

It's almost perfect!

In typical Java EE style, there's one thing that just doesn't appear to be working the way I'd like it -- it doesn't appear to honor JCDI Alternatives (at least not in Glassfish)... Here's what I'm thinking -- we should be able to have a different Config class for each of our different environments... in other words, we'd have a QAConfig that pointed to a different Derby db, a StagingConfig that pointed to a MySQL db somewhere on another server, and a ProductionConfig that pointed to kick ass, clustered MySQL db... we could then use Alternatives to turn on the ones that we want in certain environments with a simple XML change, and not have to muck with code... unfortunately, it doesn't appear to work -- it appears in Glassfish that it is processing them in an undeterministic order, with (presumably) the class that is processed last overwriting the others that came before it...

There is a solution, though, and it is on the lookup side of the equation -- using JCDI Alternatives, we can selectively lookup the DataSource that we're interested in, and then enable that Managed Bean in the beans.xml file... it's definitely not ideal, since we need to actually inject all of our DataSources into JNDI in all scenarios, but it works, it's something I can live with, and is probably easily fixed in a later Java EE release... Update: Looks like it's in the plan, according to this link -- thanks, Gavin :)

Here's how it works -- first the 'common' case, probably for a Development environment:


@RequestScoped
public class DSProvider {
@Resource (lookup="java:global/jdbc/AppDB")
private DataSource normal;

public DataSource getDataSource() {
return normal;
}
}


Simple enough -- has a field that looks up 'jdbc/AppDB' from JNDI, and provides a getter... now for QA:


@RequestScoped @Alternative
public class QADSProvider extends DSProvider{
@Resource (lookup="java:global/jdbc/AppQADB")
private DataSource normal;

public DataSource getDataSource() {
return normal;
}
}


Pretty much the same, except this does the lookup from 'jdbc/AppQADB', and it is annotated with @Alternative... so how do these things work together? Take a look:


@Named
public class Test {
@Inject
private DSProvider dsProvider;

...
}


Again, simple -- we're injecting a DSProvider instance here, and presumably running a few fancy queries... Nothing Dev-ish or QA-ish here at all, which is the beauty of Alternatives... finally, when building the .war file for QA, we turn on our Alternative in the beans.xml, like so:


<beans>
<alternatives>
<class>com.mcorey.alternativedatasource.QADSProvider</class>
</alternatives>
</beans>


You'll notice that this solution requires us to rebuild our .war file for QA, which I obviously don't like -- not to worry, there will be support for this in the Seam 3 Environment Configuration Module, which will effectively create a binding by mapping from one JNDI key to another... I have no idea what the syntax will look like at this point, but it should be pretty straight forward, and will allow us to -- you guessed it -- build our .war one, and copy it from place to place without modification...

M



Thursday, August 6, 2009

What's cool in Java EE 6 -- Singleton EJB's and Pruning

Well, with the all the excitement about the addition of JSR 330 Dependency Injection into the EE 6 platform, I figured I'd switch gears a bit and talk about the changes in a different spec -- this time, the EJB spec... Now, this spec is enormous -- 618 pages to be exact -- but luckily, we can ignore most of it! I mean seriously, who wants to read about EJB QL, 2.1 Client Views and the like... I'd rather dig into the meatier stuff, like...

Singleton Session Beans
We all know the Singleton pattern -- it may be one of the most well known designs patterns, and it's easy to understand... basically, if something's a singleton, then there's only one of 'em... ever... that means if you lose it or break it, it's gone for good... ok, that last part isn't true, and really the parts before that aren't quite true, either -- in most implementations of the Singleton pattern, folks conveniently forget to account for the fact that Enterprise applications often live in clusters, and instead they make singletons so that there is only one per virtual machine... most of the time this is fine -- they're often used for things like Service Locators, which were used back in the olden days of EJB 2 as a convenient way to do all the nasty JNDI lookups for EJB's...

Enter Singleton Session Beans... these are pretty much what you'd expect them to be -- an EJB that you can only find one of per JVM (the spec is specific about that last part, so really, they're only Singletons part of the time)... frankly, I was somewhat underwhelmed when I first heard of them, but they do add one interesting capability that I've needed on several EJB applications in the past, and have never had in an easy, portable way to pull off -- the ability to execute on application startup...

This can be achieved with a few simple annotations, like so:

@Singleton
@Startup
public class InitBean {
@PostConstruct
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void initializeSomeStuff() {
...
}



I know, lot's of annotations on that sucker, but it's pretty straight forward:
  • @Singleton -- defines this as a Singleton Session Bean... big surprise here, eh?
  • @Startup -- this is an indication to the app server that this class must be created and initialized at application startup, and yes, the spec uses the 'must', so there's no soft language here
  • @PostConstruct and @TransactionAttribute -- these are the old tags that we all know and love...
Anyone who's read this blog before may notice a hidden gem in here that makes all of this worthwhile... I'll give you a hint -- go read this entry on @PostConstruct... yes, that's right, this is a Transactional @PostConstruct method... and it will work! They got this one right when they wrote the EJB 3.1 spec, in that it guarantees that @PostConstruct methods will obey your @TransactionAttribute attributes! Now if only they would extend this capability to all EJB's, we'd have all of our problems solved! Ok, perhaps not all of them...

So anyway, you can do pretty much whatever you want in here, including initializing 3rd party systems, creating timers, sending email, truncating all of your database tables, etc... what most intrigues me, though, is data bootstrapping, similar to what you get with the Grails Bootstrap class:

...

@PostConstruct
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void setupUserData() {

List expectedUsers = getExpectedUsers();

for (User u : expectedUsers) {
User found = em.find(User.class, u.getId());
if (found == null) {
log.info("Persisting user "+u.getUsername());
em.persist(u);
} else if (!found.equals(u)) {
log.info("Updating user "+u.getUsername());
em.merge(u);
} else {
log.info("No need to update user "+u.getUsername());
}
}
}

...


In other words, this Singleton will ensure that your standard set of users will always be available upon application startup -- if this is something you want only in a development environment, you can configure each machine with environment information via JNDI, System properties, or a configuration that is set in your build so that it only takes these actions on a development environment -- it is a great way to ensure a consistent development environment across your team...

A Word about Pruning
Ok, this is, by far, my favorite feature of Java EE 6 -- and it's not even a feature! That's right, we're finally going to be able to actually remove some of the stuff that's been added to Java EE over the years! This could include a wide variety of things, but just think -- some day in the near future, you won't have to sift through details about Entity Beans, outdated communication protocols like JAX-RPC, EJB Home interfaces... instead, it will all be gone! Unfortunately, this day hasn't come just yet -- they're just telling us that they're planning to do it some day, but at least it's a step in the right direction... now I have to wonder -- will Java EE 7 actually be a smaller spec than EE 6? Now that would be impressive :)

In the meantime, you can get a little hint of the pruning goodness by taking advantage of the new Web Profile -- this is a nice customization of the spec that removes a lot of the stuff that most folks don't use anyway, but that is still pretty useful in some cases... unfortunately, you still do have to thumb past all of the extra stuff if you decide to go diving into the spec documents...

Conclusion
It seems odd to me that it took so long for Java EE to standardize such a simple, but useful piece of functionality as startup logic -- to me, this is more important than the fact that this EJB is a (kind-of-)Singleton! Sure, I've always been able to do this through an eagerly loaded Servlet, or with WebLogic or JBoss specific code, but the Servlet solution is just plain weird if I'm not acting upon my web container, and this is obviously more portable than an app-server specific piece of functionality... the above example just seems a little less... dirty to me :)

But who am I to complain about a nice new feature :)

M

Saturday, August 1, 2009

More cool in Java EE 6 -- JSF 2.0, Bean Validation

There's definitely more cool stuff in JSF 2.0 that I didn't get to last time -- so let's get right to it...

Annotations for Converters and Validators
The @FacesConverter and @FacesValidator annotations are nice little additions to the framework... they're simple to use -- you write your converter and validator classes in the same way as you always did, but instead of needing to crack open your already-way-too-large-faces-config.xml and look up the syntax for the converter tags, you can now rely on your IDE to help you out -- just throw @FacesConverter on the class with the 'forClass' attribute, and it will automatically register that converter for all form fields of the appropriate class... it doesn't get much easier than that, and of course you can use the 'value' attribute in the same way you used to use the 'converter-id' tag in the faces-config.xml, and then reference it in any of your pages...

Ok, you're saying -- so I get to add a line to my class file and take four lines out of an xml file -- so what? But wait, there's more -- and this is my favorite part... throw an empty faces-config.xml file in your META-INF folder, and these converters and validators will automatically be registered for any JSF web app that includes this jar! This is a great mechanism to promote reuse -- create a utility component that has a bunch of these files, and every one of your web apps can get them with a couple of lines in a Maven .pom file (or whatever it is you use for your builds)... I suspect it won't take long for standard sets of converters and validators to become available in component libraries like RichFaces or IceFaces...

Bean Validation
Speaking of validation, here's where it gets interesting -- with the new Bean Validation integration, it's no longer necessary to think about validation just in terms of JSF... I personally believe that validation could be better approached as an integral part of a well designed domain model (think Domain-Driven Design here), so putting that logic in a JSF specific validator has always seemed awkward -- likewise, adding a 'validate()' method that needs to be called while processing a form submit or just before persisting your object (in the case of a JPA Entity, for example) is just as awkward, if not worse... not only that, but many applications are more than just web apps -- some have batch-processing or scheduled aspects to them which don't have any exposure to JSF... using JSF validators in these cases would be a bit smelly, and duplicating the code is even worse -- this is where Bean Validation comes in...

With the annotations in the javax.validation.constraints package, we can now annotate our domain fields with things like @Min, @Max, @NotNull, @Pattern, etc, so that the validation rules that our domain objects abide by are defined right along-side the fields themselves... there is, of course, an API available for evaluating the rules against a given object, but here's where it gets cool -- JSF and JPA both provide support for this automagically! That means whenever you have a domain object that is exposed through a ManagedBean in a form, the validation rules will be executed for you, and any failures are made available through the standard h:message tags! Not only that, but the validation can also be executed when you persist or merge your domain object via JPA, so batch-processing applications are covered as well -- very cool...

A very similar incarnation has been available through the Hibernate Validation and Seam projects, but it is great to see this get worked into the standards... The basic constraints here are lean, but take care of most use cases -- I have experimented with some simple custom validators, but am looking forward to getting into some more complex rules with multiple fields and see how it handles them...

Still more?
There's still more stuff in EE 6 that I'd like to talk about, including the Facelets support and the new Composite Component stuff, but I need to do a little more fiddling with that -- I came across the new 'Behavior' API as well, which looks like a slick way to make your components do what you want, as well as make them extensible... At some point, I'm going to get my hands on Web Beans, the new JPA 2.0 capabilities, Singleton EJB's, Asynchronous EJB's, etc -- there is a lot of good stuff in this new spec, so stay tuned!

M

Saturday, September 22, 2007

Did Guice beat Sprint to the punch?

There's been a lot of talk over the past few years that perhaps Interface 21 should push to formally make the Spring Framework a part of the JEE specs -- it seemed like it might be possible with Rod Johnson officially declaring his support for JEE 6... well it looks like "Crazy" Bob Lee and the team behind Guice may have found a back door to get themselves into the party first -- according to a new series of articles about the upcoming Web Beans, the new spec is actually influenced by a combination of Seam and Guice, rather than just Seam as previous reports had speculated...

This is not to say that Guice and Spring cover the same ground -- Guice is strictly a product that supports dependency injection, while Spring does that and much more, but I find these articles interesting in that Google has apparently taken the JBoss approach to supporting the JCP -- that is, create an independent product to fill a whole in the JEE specs, and then use the JCP to make that product into a spec itself (take a look at the JPA for a previous example)...

I personally think it's a very smart approach -- while it will perhaps create an opening for competitors to get into the market (more applicable when considering Hibernate and Seam than with Guice, admittedly), it opens up a clear opportunity to provide the first spec-compliant implementation (thus getting early adopters), and gives them a great opportunity to build and enhance their product while the competition is catching up (keeping the early adopters :) )...

We'll see where this goes, but so far it looks like an interesting spec -- I see some potential for overlap between some other specs, but that may not be a bad thing...

M

Friday, August 10, 2007

More on rethinking JEE 5 patterns

Adam Bien often discusses the rethinking of JEE 5 patterns and best practices in his blog, and his latest entry discusses a replacement for the Value List Handler pattern that was prevalent in the J2EE 1.4 and earlier worlds called the Paginator. While I can't say I love the name, the implementation is interesting -- it's really not much different than the old VLH pattern, except that it returns detached JPA Entities instead of Value Objects (hence the reason for the rename)...

What is interesting is that he has implemented the Iterator interface for this implementation, and each call to 'next()' returns a full page of JPA Entities... the code is really quite simple, and I'm sure it could benefit from further use of generics to make this a reusable Stateful Session Bean, but the fact that he is implementing an interface that every Java developer knows and uses pretty much every day (well, before JSE 5 came around, anyway), can only help people realize that perhaps now we can move closer to a real object oriented design... That is definitely a Good Thing... I urge people to take a look at the code in his Subversion repository (and some of the others in there are worth a look, too!)

M

Monday, July 16, 2007

Build Systems

I will admit to being a bit ‘old school’ when it comes to build processes… I will tend to use a tool like Ant that gives me a lot of control over how a project is built, and that is often launched from a command line… I’ve given Maven 2 a chance, and I like a lot of the concepts involved, especially that of Convention over Configuration, but I found that it requires a Herculean effort to do something as simple as building a JEE 5 compliant ear file – this is apparently what happens when the Conventions are based on a previous version of a spec you’re using (to be fair to the Maven 2 project, I found that my biggest frustration was with the documentation – my issues may certainly have been user error, and may be solved with a little better documentation, but my feeling is that it’s simply not there yet)

I’ve also worked a lot with the build processes inherent to Eclipse and NetBeans, but I have not used these for any projects that I collaborate with others on – I think this is mainly because I would prefer not to restrict people to just use my favorite IDE (which most people don’t seem to like – more on that later)…

I have worked most often in a system that uses a bit of both – the best setup for me seems to be one in which the primary build is a series of Ant scripts (Maven, or something else would fit just fine here), while developers are able to work in whatever IDE they like – if that IDE provides its’ own compilation system, then great, but the code that is compiled here doesn’t actually matter for anything, because the runtime system uses the class files created from the Ant scripts…

In some ways, this feels more like a compromise system to me than anything else, and it’s often difficult to get less experienced developers to realize that if their IDE is showing that they have an error, but the Ant script still builds, then it’s not a big deal (not to mention that a situation like that just seems a bit smelly anyway)…

Do other projects work in this way, or is there a ‘better’ way, in which both the IDE and the build scripts use the same class folders? I’m willing to bet that this is doable, but I haven’t had the opportunity (or patience ) to pursue it yet…

Wednesday, July 11, 2007

Rethinking Best Practices

Ah, J2EE best practices -- the community's way of figuring out how to work with flawed technologies... You know, the Session Facade, Data Transfer Objects, etc. -- they are ingrained in so many developers' brains to the point of being second nature... It feels almost instinctual to design your system with them -- putting your data over here in these classes, putting your logic over there in those classes...

Problem is, now that JEE 5 is becoming more common, those best practices are all wrong... ok, in most cases they won't necessarily cause any harm (at least not of the magnitude of not following best practices about 5 years ago), but there are now better ways of doing things -- we just need to learn what they are...

I'll touch on a number of these in future posts, but I find that the area I have a lot of trouble with is getting rid of my habit to separate my data from my logic... the Session Bean/Entity Bean separation, in my opinion, is one of the more damaging patterns that was literally forced upon developers who went down the EJB path in the early days, and it's a pattern that I'm not convinced is completely fixed yet... more on that in a later post...

Personally, my 'toy' projects are partially intended to get me thinking away from this -- when it comes down to it, it's all about trying to relearn those object oriented design principals, incorporate some newer techniques like Domain Driven Design, and just experiment in whatever way suits my fancy...

The first thing I do is put together my initial design in some form -- either code, UML, a drawing, whatever... then I do it again, and look for specific flaws, like classes with only data and no behavior and vice-versa... of course, these scenarios aren't always wrong, or even bad, but each time I go through this retrospective, I get a little better at identifying these issues to start with...

Do you have similar experiences? Spill the beans, let us know!

JEE and Spring

How are people using JEE 5 and Spring these days? There's a lot of overlap in the technologies, obviously, and there are reasons to use both, but I'm interested in those using them collaboratively...

I've seen some articles about how one can integrate the two by accessing a Spring ApplicationContext from within an EJB 3 Session Bean, but none of them seem to address the fact that the two have different life cycles -- using dependency injection within a Session Bean's PostConstruct method could cause some unexpected problems if you're using Spring's prototype scoping... there's no guarantee that the PostConstruct will be called for each invokation, but only when the bean is originally created...

Has anyone out there dealt with this? Would it be possible to create an 'ejb' scope with Spring's new customizable scopings?