The Source for Java Technology Collaboration
User: Password:



Michael Nascimento Santos's Blog

J2EE Archives


Final JavaOne report

Posted by mister__m on May 16, 2007 at 02:51 PM | Permalink | Comments (2)

Ok, so after a long trip home, I finally managed to write the final installment about JavaOne.

In the morning, I attended Gavin King and Bob Lee's talk about Web Beans. The coolest thing about Web Beans is actually its dependency-injection support and the rich lifecycle model they are proposing. It is actually a merge between Seam and Guice strategies. It would be applicable to any kind of application, not only web-based, so my question was if they intended to split the spec so these features could be used, well, anywhere. They like the idea, but it is too soon to say. Let's hope they eventually do it. Watch out, Spring!

Then I attended the Effective Java Reloaded session. I haven't attended the 2006 session, but a few folks said it was too similar to last year's talk. I've already applied - and advocated - many best practices suggested during the talk, specially making everything final. By the way, Gavin, Bob and Joshua are great speakers and members of this group were in short supply this year. Sigh.

In the afternoon, I've (accidentally) spent some time with some NetBeans guys. First Roman Strobl:

I've told him a little bit more about my NetBeans pledge (expect a follow-up post about it). Then I came across Geertjan again, that showed me his musical notepad (you can find it at nbjfuguesupport). Guilherme Silveira was passing by and decided to make a video about it. He posted the first part in YouTube and hopefully he will upload the second part soon.

After that, I've attended the last few minutes of the session named "Stress Your Web App Before It Stresses You: Tools and Techniques for Extreme Web Testing". It was quite packed and it seems people liked it a lot. So, no need to be worried, Felipe!

Basically I spent most of the time in the afternoon and early in the evening. Then, I was at the Java Champions BOF. Java Champions are recognized by Sun as leaders inside the community. Some of them are Kathy Sierra, Bruce Eckel, Joshua Bloch, Neal Gafter, Jason Hunter, Calvin Austin and even myself. It was good to meet some of them and also to meet the program coordinator, Aaron Houston, a very nice guy.

Finally, it was show time: our BOF about JSR-310, Date and Time . As noted by Timothy O'Brien, the number of people who attended was impressive. Her is a partial picture:

We showed a few slides and some code Stephen started working on recently; we expect to commit this API to SVN soon. The audience made interesting comments and questions during the talk and after it - we had to stay there for almost an hour after our talk to address all questions. Some spec leads for JSRs that will make it to Java SE 7 were there and showed they intend to use our work and to support it. So, JavaOne selection team, keep it in mind for next year: date and time is a hot topic.

Once I had completed my main mission, I had a meal with some other Java Champions/JUG Leaders in a nearby restaurant. It was quite nice to meet these folks, shall I say.

From Thursday, I would like to highlight the excellent JFugue talk delivered mainly by David Koelle and with special guest star Geertjan Wielenga. David is a terrific speaker, his work is amazingly cool, his demos rocked and he managed to be funny. Geertjan also deserves congratulations for focusing on the main topic, JFugue, instead of just pushing NetBeans. Of course he mentioned his application was NB-based, but he actually focused on demonstrating how JFugue was simple to use, which just makes more people interested in his application and, well, NetBeans. So, another note to J1 selection team: we want more music-related talks, preferably with David!

Fabiane Nardon and Daniel Lopez's BOF, Designing Self-Evolving and Self-Configuring Java Platform, Enterprise Edition (Java EE) Applications, was also quite interesting and attended by several Java Champions. Nice job! The BoF I've attended after it was one of the coolest sessions in JavaOne: The "java.lang.OutOfMemoryError: PermGen Space" Error Message Demystified, presented by Frank Kieviet and Edward Chou. I couldn't believe they could actually spend 50 minutes talking about this topic with valuable information, but they actually did it. Having done a lot of profiling and OOME chasing before, I must say I could not explain the issue better. You must be on the Rock Star Speakers list for this year.

Fabiane and Edgar's session on Friday was very successful as well and Linda deMichiel and Kenneth, from JPA 2.0 and EJB 3.1, came to them after the session to look for input for their specs. Joshua's Puzzler session was really cool as well.

So, it was nice to meet everyone I didn't know in person before and to talk to all of you I've already known. See you in JavaOne 2008 (if any of my submissions is approved)!



More about Practical AOP and Transparent Remoting

Posted by mister__m on January 04, 2005 at 10:53 AM | Permalink | Comments (1)

I am glad my original post about Practical AOP and Transparent Remoting has received polite and smart comments against it. This is definitely a nice way to get the discussion about AOP going! Here are my answers to these comments.

First of all, cajo said that "this is a perfect example of why I fall into what you call your third AOP viewpoint. As you said, magic happens; but it is also totally invisible from the actual source code. I can't imagine how one would debug a complex application." I am sure this is a reason why many developers are concerned about AOP adoption. But let's address this question to see if this point should prevent us from using AOP.

First, how do you debug such application? If you simply use your IDE "Step Into" debugging functionality and you happen to have genesis sources available, your debugger will stop at the advice's first line. And then, everything will be simple to understand. But maybe the real question is: how would I guess I should step into at that line? To answer this question, we just need to think about how we decide to use step into when debugging our OO applications.

If you have a snippet like:


public void aMethod(SomeClass o) {
   o.someMethod();
}

You already cannot assume you should look for someMethod() implementation in SomeClass in this simple example. Why? Because you might be dealing with a subclass or maybe a proxy. And if SomeClass is an interface and the instance you received is a dynamic proxy, it becomes even harder to debug. So, if there's any chance you're dealing with a polymorphic call today, you already have to guess whether the code being executed belongs to SomeClass or is defined on another class. "Hey, but I don't have to guess; I can use Step Into today", someone might say. And that's just what I said a few lines above. You should use Step Into in these cases to be sure what code is actually being executed. The only new thing with AOP is that it may happen with any method, but it is not different from today.

Besides that, either your aspects should affect well-defined points in your code or you should use a tool. AspectWerkz provides an Eclipse plugin that helps you to see which methods are affected by advices, for example.

Then, cajo proceeds:

Consider operator overloading: Many argued against its inclusion in Java, because it could make the source look less obvious. To me, this source looks far less obvious.

Well, except for String concatenation tricks - which shouldn't exist for consistency, anyway -, I agree about operator overloading because it already has just one meaning. But as I showed above, a method call is already "trickier".

Another interesting response came from jhook. He begins:

I can't necessarily argue with what Michael is trying to accomplish, just in how it's being accomplished. The problem with many of these AOP implementations is that you are modifying the behavior of an object for everyone. The behavior of RemoteClass is intrinsic, adding a client's ability to remote 'helloWorld' is extrinsic to RemoteClass and IMHO shouldn't be applied for all clients of RemoteClass (at compile time).

Some of that's true, indeed. For this specific case, my intent was that every RemoteClass client had to access it through the aspect. But it only affects clients that have access to the weaved version of the class. So, in the server side, we keep a "regular" version of it and no remoting is necessary. This is one approach to actually do what jhook suggested: use the class version you want.

Another approach is to change your pointcut to intercept calls to the method and not changing its execution as the default aop.xml that comes with genesis empty-project does. That's the beauty of AOP: this behaviour is actually extrinsic to the class, since your configuration will determine whether method execution, call or none will be affected by which advices you choose.

The last comment I would like to reply to have been made by ablperez. It says:

A cleaner example of AOP's power would have been taking a POJO and making it transactional. Objects that are remotable should clearly relflect that. This example commits the fallacy "The network is reliable" from the eight distributed computing fallacies. A well defined remotable object should declare to throw a remote exception. IMHO remoting is not something you want to hide.

Well, that's debatable. How would you handle the RemoteException? Rethrow it in every method that calls this class? Write tons of try/catch blocks spread throughout your codebase? A cleaner approach would be to handle it once, in one single place. Since Thinlet - and therefore genesis - already defines a single point for handling exceptions, you can do it once in a base class. However, if you do think it's nice to be more explicit, just add a throws java.rmi.RemoteException to the method's signature and handle it as you wish. The exception will be thrown as you would expect.

It's important to mention that genesis default project structure is targeted to intranet environments, where bandwidth shouldn't be a problem most of the time. Besides that, a timeout aspect is applied to every remote call to make sure it either completes timely or a timeout exception is thrown. So it actually expects delays to happen. The default aspect doesn't do any fancy stuff, such as displaying a wait dialog or something like that. This should be customized on a project basis.

I hope we can keep this healthy discussion going, since I think it just helps the community as a whole. By the way, a new genesis release, 0.2-beta2, is now available. Its documentation is available if you are interested. I'll be saying more about AOP soon. Stay tuned ;-)



Practical AOP (Part 1): Transparent remoting with AOP and EJBs

Posted by mister__m on December 17, 2004 at 01:44 PM | Permalink | Comments (4)

There are basically four views about AOP nowadays (ok, it's more or less the same for any technology): those who think it's the golden hammer and everything is a nail, those who think it has some applicability, those who are strongly against it or have deep concerns about its wild adoption and those who simply couldn't care less about it. :-) I hope this kind of posts I intend to write help all the four groups in some way.

Let's start with an example most people are familiar with: remoting. Many technologies try to address remoting with different approaches - RMI, CORBA, EJB, webservices etc. - and each one has its own applicability, since most of them (are intended to) do more than just remoting. Also, these technologies can be implemented in several ways - consider the way EJB implementations in application servers has evolved, as an example. So, let's narrow our requirements for this case of study:

  • Remoting should be transparent to the user. So, this means not even lookup or interfaces should be necessary for a user to call a remote component.
  • We want to keep the benefits provided by EJB technology - security, transactionality, etc. - but without any complicated constraint on our code. We don't want to write tons of rules for a Hello World.

In a simple way, we want EJB benefits without any of its limitations. How could we implement this?

Using genesis this should be as hard as:

public class RemoteClass implements java.io.Serializable {
   /**
    * @Remotable
    */
   public void helloWorld() {
      System.out.println("Hello world");
   }
}

public class Client {
   public static void main(String[] args) {
      RemoteClass remote = new RemoteClass();
      remote.helloWorld();
   }
}

If you run this example using a genesis empty-project based structure, putting RemoteClass in your shared sources dir and Client in your client sources dir you will see that "Hello World" actually gets printed in your application server console. How this magic happens?

genesis' aspect named net.java.dev.genesis.aspect.EJBCommandExecutionAspect intercepts execution of methods annotated as @Remotable as defined in aop.xml and executes the method call inside a Stateless Session Bean in the server side. Since you have a simple POJO, you are not constrained and can take advantage from any OO feature you want, including instantiating a remote object with new if that's what you want, and you still get all the benefits from EJB technology. It's a much cleaner approach to remoting than other ones currently available and it's certainly going to be expanded on future releases to support full Session Beans semantics with plain POJOs - as well as the current model.

For further information about how this actually is implemented by genesis, refer to the documentation pages for genesis aspects and genesis business component model.



Announcing genesis

Posted by mister__m on December 13, 2004 at 10:27 AM | Permalink | Comments (1)

A few weeks ago, we've silently released the first public beta version of genesis. But what is genesis about?

genesis is open-source software (LGPL) and its main objective is to allow you to build powerful, scalable applications in a simple, productive and testable way. Although its long term goals are much more ambitious, right now it focuses on two main areas:

  • UI programming: your form is just an annotated POJO and... that is it; no further requirements. Annotations will allow you to automatically populate comboboxes and tables, to enable/disable widgets, make them visible or not, clear fields based on conditions etc., in a declarative way. Programming a complex UI becomes a very simple task, which is one of the main reasons some people still avoid using Java on the desktop. The current implementation uses Thinlet as the view technology, but other APIs, such as Swing, will be supported soon.
  • Business components: many "modern" frameworks support a POJO model for business components, but there are still several limitations - a business object cannot be directly instantiated, but rather injected or looked up using a factory, for example, or you have to expose your POJO using an interface or otherwise you won't be able to take advantage of most facilities offered by these frameworks. genesis takes a different road: you can use new to instantiate your components and they don't have to implement or be exposed by any interface in order to take advantage of genesis' facilities. In runtime, depending on your configuration, genesis may use EJB technology to execute your POJOs as if they were Stateless Session Beans or you can work in local mode (which is cool for some desktop applications). You don't have to change a single line of code to switch execution modes, but just use a different target to build your application. Current genesis features include transparent remoting, transactional support and DI (dependency injection) for Hibernate. General DI will be supported soon.

genesis does not try to reinvent the wheel, but rather builds on top of several other open-source projects to deliver its functionalities. Besides Thinlet, this release relies heavily on AspectWerkz and AOP to implement a flexible core so that new ways to do remoting or to configure a form - using xml, for example - are easy to write and don't require any changes to existent genesis code. So, if you are looking for practical ways of using AOP, check out genesis sources.

genesis is already running on production environments and, in one of them, the server-side application is capable of handling more than 1.125 million transactions per day with a single box. You can access genesis docs and download it at https://genesis.dev.java.net

UPDATE: genesis was the 2nd largest java.net project by commits last month according to this report, so it is really worth a quick look. ;-)



AspectWerkz 1.0 RC 1 is out

Posted by mister__m on September 03, 2004 at 07:05 AM | Permalink | Comments (0)

I should say I am somewhat "attached" to the innovative open source projects I use in my job. Besides Thinlet, a very lightweight and intuitive XUL framework that doesn't use Swing, AspectWerkz is the one I've been more actively involved for the last months. Its approach to some problems is unique and they have very nice features, such as their support for typed and untyped annotations, for example. It focus on dynamic AOP, use a Java-based approach (no strange plugin is required for your IDE to actually "understand" your aspects) and allows both online and offline (runtime and pos-compilation) execution modes. Maybe the most fantastic thing about AW is that Jonas Boner and Alex Vasseur, founder and developer, are very responsive and actually implement most features users request very fast.

Today, AW 1.0 RC1 was announced. AW is almost two-year old and very stable (I've been using it in production applications since 0.9), but the fact it didn't have a 1.x release pushed some users away. I am also very proud we - me and Allan Jones, a co-worker at Summa Technologies - were able to contribute to this release. It is a stable, production-ready release. We migrated a project this morning and all the unit tests pass.

If you haven't downloaded it yet, do it and use it. You won't regret, I am sure.



EJB 3.0 Early Draft Spec is now available for download

Posted by mister__m on June 30, 2004 at 09:33 AM | Permalink | Comments (0)

The Expert Group for JSR-220 has just published an Early Draft of the new EJB 3.0 spec. It is available for download at the JCP site.

If you want to know more about JSR related news and to participate in their active development whether you are a JCP member or not, check out the recently launched JSR community.



EJB 3.0 - Is it going to solve our problems?

Posted by mister__m on May 19, 2004 at 01:01 PM | Permalink | Comments (1)

UPDATE: Brazilian Portuguese translation / tradução para o português do Brasil no JavaFree

To begin with, I must congratulate the JSR-220 EG for their braveness. I can't think of any spec in the JCP that has been changed in such a dramatic way as this one. Linda said during the last JavaOne she intended to kill deployment descriptors and to simplify the programming model as much as possible. However, I never thought the EG would take that words so seriously and would drop the current model - ok, "drop" may sound too strong, but, even though they are going to support it, anyone writing code will prefer the new API unless there is some political/business objection for not doing so - for a POJO-based one.

So, now it's time to explain why I think we can simplify EJB 3.0 even more and give tremendous flexibility for the hardcore developer without making any EJB look cluttered or ugly (some people said Linda stated it still will be necessary to use the "old model" for some hard stuff; this sounds extremely unpleasant to me, I must say). The new programming model for EJB 3.0 seems to rely heavily on annotations. This certainly is a good thing compared to the deployment descriptor hell, but there are two things missing that would make turn this idea into something really powerful:

  • Annotation processors: what do you do when the security capabilities of your app server are insufficient or inadequate for your needs? Change vendors? But what if the first vendor has a feature you need, but that the second one doesn't offer something similar? That's one of the flaws we're still keeping: vendors will implement the spec in some way that may not be what you need/want. And what can you do about it? Almost nothing, besides throwing your app server away or relying on a non-standard solution - sometimes, it means not using EJBs for a part of your project they'd be the perfect fit if only that feature had been implemented in a better way by your app server vendor. What if you could write implementations for the services an EJB container should offer? You may now say: "hey, but that's exactly what I've paid for", but it's often needed. Vendors are not capable of foreseeing every need you'll have. It'd be even better if we had a standard spi for all the services an EJB container is supposed to provide. In that way, you could swap small components or, even better, write a decorator around a app server specific implementation so that you could only provide the one missing functionality you need - instance-based security for entity beans, for example - and delegating the other features to your app server default implementation. Imagine how many problems you would be able to solve if you could change or augment the functionality provided by an application server in a standard way! I can tell you it would solve around 80% of my issues with EJB. The other 20% would be solved as shown below:
  • Support for custom, user-defined annotations: frequently, we need to add services to our components that are not part of the EJB spec. If this feature is not so domain-specific, chances are some vendor has provided support for it. And then, welcome to vendor lock-in! You are left with two choices: go for vendor lock-in or write terrible code just in order to have a portable application. Wouldn't it be nice if you could solve it in a elegant, portable way? Custom annotations and custom annotation processors could be the answer. Imagine if you could write an small session in an deployment descriptor declaring a custom annotation and an implementation of an interface, AnnotationProcessor, that's capable of handling it. You could define your own implementation or simply delegate the processing of your custom annotation to a class provided by your container of choice. You could get portability and still benefit from non-standard features your vendor offers you. Annotations without properly-configured processors would be simply logged at deployment time, since they could be there for a nice reason - for example, you might want to "tag" your methods for some functionality first and implement it after; or maybe that annotations are meant to provide enhancements during runtime and don't represent essential services, like caching, for example.

I am pretty sure some people will say: "Spring (put your favourite lightweight? container here) can do that" or "this is a case for an AOP-based container". I totally agree with the first and I think an AOP-based container would be a good implementation, but the real point is: these are not standards. There is only one Spring - some people might be writing a few implementations for its interfaces, but they are just some people, not major vendors with hundreds or thousands of experienced employees working full-time on that - and AOP frameworks I know are completely different from each other. If we could come to agreement on what basic services an EJB container should provide, a SPI for them and a way to plug custom annotations and to process them, we could get ease of use with maximum flexibility and ability to choose without limiting you to rely on a single vendor for the rest of your life. Vendors would have to provide amazing implementations for each EJB container service and offer a lot of high-quality custom services if they wanted to keep up. A new market of service providers would arise and we'd see a constant increase in the quality of each comercial container out there.

Besides that, there's another idea that annoys me: who said an interface is always a good thing? Even if the container generates it, I am sure I'd be glad to write:

OrderService os = new OrderService();
os.processOrders(orders);

instead of using a container-generated interface for my sesion bean. Plain Java code is great! If I don't need to use some javax.ejb.SessionBeanFactory or to have use a DI container in order to provide interface implementations to my client components, I can hire almost any person who knows basic Java to work with me in my enterprise projects and knowing I won't have to teach them a thing! That is easy of use. Interfaces are needed for a lot of reasons but, as I stated above, they are not always wanted.

Several techniques would be necessary to make these ideas work inside the container - a post-compiling phase, CGLIBed classes, etc. - but that's not my concern at the moment. If I am able to have a similar architecture right now using AspectWerkz - one of the greatest pieces of software I've ever came accross, with incredible support -, why can't enterprise vendors provide something similar?

I am sure that some people would still object saying this would be best addressed by an AOP JSR and a lightweight container JSR, but let's face it: EJB 3.0 started one year ago and it's expected to be finished next year; if we start these other JSRs now, when are we going to see a compliant implementation of them? Besides that, I am not asking for full AOP support; I just want annotation processors and maybe vendors would need to use AOP, CGLIB and/or custom class loaders for achieving my plain Java model. It may not be perfect, but it's better than what we have now in my opinion. What vendors would have to do to support the features doesn't concern me; all I want is a standard solution, with competing implementations, that offers me simplicity, total flexibility and portability.

I do hope someone from the JSR-220 EG reads this blog and post some comments about these ideas.

PS: I really think the JSR-220 EG members are doing great things and think their work must be acknowlegded and praised. They are doing the right thing, although it's hard to do. I just want more :-D. Don't get me wrong: Spring rocks, as well as Pico/NanoContainer. And AspectWerkz will be part of all my future projects unless my client objects, you can be sure. :-D

PS2: This post is inspired by the fact that, several months ago, I posted here some suggestions on how to improve the spec. They were not as drastic as the ideas presented during the last TSSS, but they addressed the most annoying issues I had to face with EJB at that time. Ease of use was, at that time, in my mind, very important for wide adoption, but my post reflected things that even XDoclet and my own frameworks couldn't solve in a decent, clean, non-application-server-dependant way. What amazes me now is that apparently most of those issues aren't going to be addressed by the new spec. Since I wrote that entry, I've been involved in lots of projects and got to know the now popular lightweight frameworks, besides getting my hands dirty with AOP. And I must say that, after playing with these ideas for a while, I got to understand things really must be simpler for the regular work - 95% of it -, but that I still do need a lot of flexibility. And I don't want this flexibility to make my code look harder when I use fancy, obscure, powerful features; I want my business code to always look as simple as the rest of my codebase. The only complexity I want to face is the inherent complexity of my business problem.



Stop the hype about webservices!

Posted by mister__m on January 09, 2004 at 07:44 AM | Permalink | Comments (31)

I know, I have never been really aggressive in any of my posts. The problem is that, even though there are some wise people - I am not wise, I am just reasonable - telling people they are doing bad things, they keep on doing it. I ought to speak out, then. I have no choice. I can't see people doing something so irrational and still remain silently. Sorry folks, if this entry offends you, but this time it is necessary. It is for your own good. It's like taking medicine that tastes horrible; you don't like it, but it is for your own good.

So, what are webservices for? No, I am _not_ talking about technical definitions here. The real question is: what are webservices meant to be used for? That's hard to answer. So, I'll explain to you what most are missing by answering the simpler question, in my opinion: what are webservices not meant for? Let's go for a couple of examples:

  • Webservices are generally not the right technology for integrating two systems written in Java. Yep, that is a fact. If that is what you are using webservices for, you probably should forget about it. It is very likely you are just wasting time: CPU time and development time; you are also wasting network bandwidth. Why do you insist on using webservices for that? If two people can speak English fluently but are very bad at Japanese, so bad that if they see anything in Japanese they have to translate it to English word by word in order to understand it and if this process takes a considerable amount of time, do you really think they should talk in Japanese, even knowing they will never improve their ability to speak in Japanese by doing so? It may surprise you that most people using web services are, in effect, doing just this double translation every day. If you are one of those, please, explain it to me. I don't get it. So, maybe you intend to keep your systems loosely coupled. I understand that. But let me ask you some questions:
    1. Should they be loosely coupled in first place? Sometimes two systems are so tightly coupled that they should be just one system, to begin with. This usually happens in big companies, where political reasons force two groups to buy two solutions from two different vendors to solve two parts of the same indivisible problem that cannot be addressed separately. A sad reality, though.
    2. Doesn't plain old RMI solve your problem? Think about it and tell me why it does not. If you come up with a good answer that is not "RMI limits me to using Java" and that cannot be applied to webservices, maybe you have a point.
  • Webservices are generally not the right technology for integrating two systems for which there are better forms of integration. I am totally in favour of maintainability. I am not telling you to use plain sockets for anything not extremely simple. Have you ever heard of RMI/IIOP? J2EE containers support it; so, you have intrinsic support for CORBA in J2EE. Generally, the "other side" also supports it. It has been there for a very long time, its implementations are very stable, its a binary protocol. Why not using CORBA? Just because it isn't hype?

In my own experience - and what my friends have been telling me just proves me I am not wrong -, XML processing takes from 25% to 95% of the total processing time for most usages people are making of it. It is perfectly ok to use XML for configuration; it is generally parsed while your application is starting up, so, there is no real overhead to the end user if it's correctly implemented. But people are using XML - not just webservices - for a lot of reasons; they are using it for generating HTML when JSPs, Velocity or whatever would be faster and simpler by far. Then, they say: "it is easier, because designers don't have to deal with Java". Is it really a good reason? Let me see: you have to convert all your objects to XML - a slow marshalling operation, in most cases -, then someone has to write XSL - if it is the designer who writes it, I am sure s/he would get JSP, JSTL and Velocity; if it is the developer, s/he has to constantly rewrite it as page design/flow changes - and a big bloated XSLT processor has to run - don't tell me that just because now you can compile xsl it is better than plain old Java code. Are there any advantages if you are using Java in both ends? Don't tell me about future uses; future uses may require overhead. I am talking about the system you are writing right now.

There are some situations where using webservices might be wise; if you are integrating with .NET, they might be a good choice - note that they might; it does not automatically mean they are the only technology for the job. There are some other uses, which I am not going to talk about here - as I said, this post is about when not to use webservices. There are some binary formats for webservices, but as far as I could use them and heard people talking about them, the only impression I get is they are still slower than RMI. Webservices might be a good choice for situations where you don't know in what language your clients will be written. Even in such cases, it won't hurt if you expose some plain old interfaces and maybe RMI interfaces too. In fact, a lot of systems will perform better. No, there is no maintainance nightmare here because RMI interfaces and WSDL should be automatically generated. Period.

If you are still concerned about loosely coupling, think: What really makes systems loosely coupled? Interfaces. That is it. Integrate your systems using interfaces and provide them for whomever wants to call your code. If you are using EJBs, use local interfaces until something forces you to use remote interfaces. Use business delegates to access them and make each of their methods throw a CommunicationException and have a factory for building their instances. Why? If your backend implementation uses local interfaces, CommunicationExceptions will never be thrown, but your code will have to handle them. When - if necessary - you change to remote calls, your system will keep working, because it was ready for handling those exceptions! Then, if you have to use webservices because someone decided your backend should be written in .NET, you are still safe! Isn't that great? I'll give you one more tip: if you design your systems using naming conventions and standards, you may be able to implement all your factories and business delegates using dynamic proxies! It'll take less than 100 lines of code and your architecture will be prepared for future changes!

To sum up, If you are going to use webservices, think before doing so; it is very likely there are better options.



A simple method call: that is all it takes

Posted by mister__m on December 29, 2003 at 06:56 PM | Permalink | Comments (0)

Not having the burden of managing transactions by yourself - a.k.a Container Managed Transactions, CMT for short - is a compelling reason for using EJBs. Obviously, EJB is not the only technology that gives you that, but that's a entirely different discussion. Back to the point, the fact you don't have to call any transaction management method neither in java.sql.Connection nor in any class contained in javax.transaction makes a lot of people happy - especially those who already experienced the painful job of calling these manually. Although CMT is good and works - ok, in decent containers, let me be sincere here -, it is not magic and you have certain rules to obey so the container can do its job.

The most obvious thing - at least it should be - you should do is to specify which transaction attribute applies to each method in each EJB you wrote. There are a bunch of ways of doing it in the deployment descriptor, from specifying different attributes to each overloaded version of a method to using the same for all of them, and some containers have decent default values for when you don't declare anything, but I'm not going to cover this here. Today's point is more subtle than that and is something I've seen a considerable number of developers - including some good ones - not doing: calling setRollbackOnly().

javax.ejb.EJBContext, superclass of EntityContext, MessageDrivenContext, SessionContext is the interface that contains this method. The J2EE 1.4 javadoc description for this method is:

Mark the current transaction for rollback. The transaction will become permanently marked for rollback. A transaction marked for rollback can never commit. Only enterprise beans with container-managed transactions are allowed to use this method.

Note that only EJBs that use CMT - most of them - are allowed to use this method. But when are they required to? When it must be called? The answer is relatively simple, but astonishing for some people (from now on, everything here refers to CMT EJBs). Let's start to answer these questions by taking a look at section 17.3.4.2 of the recently published EJB 2.1 spec:

Typically, an enterprise bean marks a transaction for rollback to protect data integrity before throwing an application exception, because application exceptions do not automatically cause the container to rollback the transaction.

I highlighted the bold part and I wish it was already printed in bold in the pdf, actually. A lot of people read this section and simply ignore this important sentence. An application exception does not cause the container to rollback a transaction. It is a simple, but ignored fact. But what is an application exception? Section 18.1.1 defines it:

An application exception is an exception defined in the throws clause of a method of an enterprise bean’s home, component, message listener, or web service endpoint interface, other than the java.rmi.RemoteException.

Enterprise bean business methods use application exceptions to inform the client of abnormal application-level conditions, such as unacceptable values of the input arguments to a business method. A client can typically recover from an application exception. Application exceptions are not intended for reporting system-level problems.

Although the explanation is somewhat deceiving - Java won't stop you from declaring any RuntimeException subclasses in yours throws clause, but that won't make them application exceptions -, I think you got the point. Transactions are not automatically rolled back when you throw your custom Exception-derived instance. The same does not apply to system exceptions, as section 18.2.2 points out:

The Bean Provider can rely on the container to perform the following tasks when catching a non-application exception:

  • The transaction in which the bean method participated will be rolled back.

So, if you throw a RuntimeException or a javax.ejb.EJBException to wrap a checked exception, you are safe. Let's see how we could perform the classical withdraw operation in a Entity Bean:

// Some code goes here

public BigDecimal withdraw(BigDecimal amount) throws InsufficientBalanceException {
  BigDecimal balance = getBalance();

   //Ooops, trying to do something that shouldn't be done
   if (balance.compareTo(amount) < 0) {
      // This call is necessary as the exception to be thrown does not derive from RuntimeException
      entityContext.setRollbackOnly();
      throw new InsufficientBalanceException(balance, amount);
   }

   balance = balance.subtract(amount);
   setBalance(balance);

   return balance;
}

// And more code goes here

Throwing a checked exception is not enough; you need to call setRollbackOnly() so things happen as you expect. It is a simple truth most of us ignore and maybe that's why sometimes there is some corrupt data in our tables - the container will commit any modifications you performed before throwing an application exception unless you've called setRollbackOnly(). If you don't call this method, throw application exceptions after modifying data and never seen this error, consider it to be a bug. Really. And start looking for another container, there are plenty out there. :-D It won't be any fun when your broken container rolls back a transaction that should be commited...

To end up, be aware that setRollbackOnly() does not work all the time. Section 17.6.2.8 explicitly says:

The container must throw the java.lang.IllegalStateException if the EJBContext.setRollbackOnly method is invoked from a business method executing with the Supports, NotSupported, or Never transaction attribute.

So, if all you are bean methods are configured with the Supports attribute, you there is no (standard) way to programatically rolling back transactions! It is creepy, scary and terrifying as it sounds! Pay attention to your transaction attributes! And do not forget to call setRollbackOnly() whenever it's necessary!



Crazy JSTL: when an empty Collection is not empty

Posted by mister__m on November 27, 2003 at 08:32 PM | Permalink | Comments (2)

Previously, I have promoted JSTL as an easier way to code the web tier. While I haven't changed my mind about it, I have just come accross one of its pitfalls yesterday, a few minutes after writing a blog entry about grid computing. Have you ever been in a situation code that looked impossible to be incorrect actually was incorrect? Well, it happens in many occasions, generally in the most unwanted ones - as it did yesterday, when it was around 3 am in Brazil.

Let's go straight to the point: for those of you who are familiar to JSTL, consider the following code:

<%-- Block 1 --%>
<%@ page import="java.util.Collection" %>
<%
    Object o = request.getAttribute("collection");
%>
<%= (o instanceof Collection) && ((Collection)o).isEmpty() %>

<%-- Block 2 --%>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>

Assuming the first block prints true and that the Collection implementation used is flawless, what does the second block prints? true, right? Wrong! The right answer is: it depends.

Wait a minute: it depends? But how? Verbatim from the JSTL spec 1.0, section 3.8:

To evaluate empty A:
    If A is null, return true,
    Otherwise, if A is the empty string, then return true.
    Otherwise, if A is an empty array, then return true.
    Otherwise, if A is an empty Map, return true
    Otherwise, if A is an empty List, return true,
    Otherwise return false.

So, the JSTL 1.0 spec says nothing specifically about using the empty operator to evaluate Collections; it just supports the intended behaviour - the one we would expect - for Maps and Lists, and not all Collections. If you happen to have a Set implementation as your Collection implementation, for example, it won't work. The empty operator support in JSTL 1.0 is just for null, Strings, arrays, Lists and Maps, not for Sets. It's simply bad, too bad it works this way.

A good reason for people assuming it works like this is that most articles and presentations about JSTL say empty works for Collections. Just to mention a few examples, articles published at OnJava, IBM DeveloperWorks and even java.sun.com wrongly state it. But why can it simply return true although the spec doesn't mention it? Well, because it cannot be considered an omission. The spec says that otherwise, it must return false. Otherwise sadly covers Sets and any other Collections implementation that does not descend from a List. Sad, very sad indeed.

Are we doomed to look for alternatives approaches? One of them that works is using ${collection['empty']} when we are sure we are dealing with a Collection. Using a straight property access construction won't work as the property has the same name as the reserved operator. Fortunately, the Expression Language definition specified in JSP 2.0 has fixed the issue by replacing the line that mentioned List with:

   Otherwise, if A is an empty Collection, return true,

So, if you are using JSP 2.0, it's not a problem for you. However, be careful about JSTL 1.0 and this bizarre pitfall. I tried to warn you :-D



Why is everyone talking about grid computing? And what are you doing about it?

Posted by mister__m on November 26, 2003 at 07:11 PM | Permalink | Comments (4)

"Grid computing" - though it was quite an unknown concept till a few years ago, now everyone is talking about it. Some are saying it is everything we were missing, the next big thing. Others, as some java.net bloggers, are simply skeptical and uncertain about its practical use. But the fact is many huge companies, such as Oracle and IBM, are investing a lot of money on that - and that's a good reason to take a closer look at it.

To begin with, what is grid computing? Grid computing is about spliting your work in small pieces - or jobs, as you prefer - and assigning those pieces to different computer on the network. After they have been processed, you get them together and your main task is done. But what is the big advantage of applying grid computing?

Have you ever thought about reducing the time your Ant builds take to run? What if you could use other developers' machines to run it in parallel while they are having coffee or are out in a meeting? Wouldn't that be great? And what if you could perform parts of a specific transaction in some machines available in a cluster instead of loading one box for a minute when the user could get the response in a few seconds? Those are the kind of things that may be accomplished with grid computing in an easier way.

So, what is the Java standard for grid computing? None. Soon, there will be one and then we will have to accept it, whether we agree with the way it will be or not. If you are among the ones who hate EJBs - I don't, just gave my own suggestions previously here -, or that think that JSPs are a big mistake, stop complaining! Get involved. Talk to the ones who are defining the standard. Go to grid forums, talk to the guys at Sun One Grid Engine, move! Download one of the many implementations available, such as Globus or Sun One Grid Engine, use them, share your thoughts about it! Tell the community what you like and what you don't and why.

Grid computing will be very useful to many people in the future, but if it is not useful for you tomorrow, well, maybe that's why you didn't try to shape its future when you had the chance...



A few words about Brazil, Java technology and myself

Posted by mister__m on August 04, 2003 at 12:15 PM | Permalink | Comments (9)

If you have been to the last edition of JavaOne, then you probably have seen me :-) I was one of the crazy, shameless Brazilian guys who attended the conference this year. No, I wasn't the "Brazilian superman", as one guy who works for Sun named Bruno Souza, our Javaman. :-) But, getting back to the point, there is a lot more about Java development and Brazil than you might know.

To begin with, as Manoel Lemos and Beatriz Leao mentioned at their session, we speak Portuguese - yes, we don't speak Spanish and we are more than 50% of Latin America, what means most latins speak Portuguese! We are the 12th largest world economy and our capital city is Brasilia, not Rio de Janeiro, Sao Paulo nor Buenos Aires (that last one would make some of us really angry :-P) And some national wide projects are entirely or mostly Java technology based. Oh, probably the most surprising fact: our JUGs are the largest of the world! The #1 is SouJava, which I am glad to be part of and help to coordinate.

As this is my blog let's talk a little bit about me: currently, I am working on a application that is going to be used by one of the main industry players here and it's going to control nearly everything they do. My Ant builds are taking ages - ok, 5-7 minutes, but that's ages from a Java developer perspective :-P - and I think our code base is still going to get 5 times bigger! That is what motivated my java.net main project, called AntG. Its main purpose is to make Ant builds run faster by using threads and taking advantage of grid computing. If you are interested, check it out! Give your suggestions and join the project. We are still limiting its scope and deciding how to begin to implement it, so all of you are welcome. Right now, we are discussing everything in Portuguese, since we are all Brazilians, but if you join, identify as a non-Portuguese speaker and we'll do our best to write in a language you understand - as long as it is English or Spanish. :-)

I intend to publish some useful and practical tips here and also to talk about my other projects, so keep checking my blog out.

Regards,
Michael "MisterM" Santos





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds