The Source for Java Technology Collaboration
User: Password:



Michael Nascimento Santos's Blog

January 2004 Archives


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.



Things that could be different - Part 1: Exceptions

Posted by mister__m on January 07, 2004 at 12:53 PM | Permalink | Comments (6)

Exceptions are a new concept for most people when they get to learn Java. Even though C++ offers some degree of support for them, a number of C++ programmers never heard of exceptions since the language they were used to did not force them to handle or declare exceptions. Other languages are said to have them as well - such as Ada, though I just read this information a few times and know nothing about it -, but no language addresses the issue the same way Java does.

Checked exceptions are a great idea because they force you to accept the fact things can actually go wrong. The more skilled we are, the more we tend to think our code is (almost) perfect and that there is absolutely nothing that could possibly go wrong in that small block we are working on now. Exceptions work as a remainder that something in the environment may not be properly configured and help us to remember the fact that, as humans, we do write code that does not work - and that we always will, though good programmers tend to write it less often. That being said, let's move to the most relevant part of this entry :-D.

So, let's think about it about the way exceptions were designed. To begin with, why does RuntimeException descend from Exception? Lots of frameworks and APIs - EJBs, for example - assume that RuntimeExceptions are system errors that they should handle in a special way - by discarding the instance that has thrown it and rolling back any pending transactions, for instance. So, if you, as programmer, for any reason, decides to write code like that:

try {
   ...
} catch (Exception e) {
  //do something and...
  throw new BusinessException(e);
}

while using these technologies, you'll prevent RuntimeExceptions from being propagated to the upper calling context while maintaining their proper meaning, probably resulting in something entirely different from what you meant. If you need to write code like above - ok, it is a polemical issue, but sometimes it is indeed needed -, you have to catch RuntimeException before catching Exception and rethrow it. What if it was the opposite? What if Exception descended from RuntimeException? Or even better: what if Java had a Exception class with two subclasses: CheckedException and UncheckedException?

That would make exception handling more powerful, as you would be able to handle just checked exceptions (CheckedException), just unchecked exceptions (UncheckedException), all the exceptions (Exception), just errors (Error) or everything that could be thrown (Throwable), without having to remember to "exclude" any type of exception you didn't want to handle.

Another thing that could (should) be different is the inheritance hierarchy. Before JDK 1.4, for example, there was no support for exception chaining. So, lots of developers out there rolled their own solution for this problem at that time. And it wasn't clean or nice, actually. Why? The problem is that there is no easy way to extend the exception system because it relies on inheritance.

People wanted to add a cause to an exception so they could wrap the "real"exception inside a reasonable exception for each application layer. How could it be made? It would be nice if you could just create a subclass of Throwable or (not so good but acceptable) if you could add this behaviour in a subclass of Throwable and then write subclasses of Exception, Error and RuntimeException that inherited from your Throwable subclass, right? But that was not possible, unfortunately. That would require multiple inheritance. If you wanted to implement this simple change, you had to write at least three subclasses - one for each of Exception, Error and RuntimeException - and all of them had to have the same methods declared and implemented. If you wanted to avoid repetition, you had to design a fourth class just to hold the Throwable that caused the exception and provide a getter and a setter, but you still had to implement those methods in your three subclasses and keep a reference to an instance of your fourth class in each of them. Awkward, ugly, terrible are not strong enough to describe this solution.

How could this problem be solved? Actually, that's a pretty complex question with many answers. Exceptions could be based mostly on interfaces and just use one superclass. We could have an Exceptionable class we would have to inherit from, and have three interfaces that would allow a class to be treated as a checked exception, an unchecked exception or an error. Or maybe the throw clause could be different, allowing us to do:

throw e as UncheckedException;

, which would gives us even more flexibility because we would be able to throw the same exception instance as either a checked or an unchecked exception in different contexts. Obviously, we'd still want to have a superclass we were forced to extend in order to be a valid parameter to the throw clause; otherwise, Integers could be treated as valid throwable instances - something ugly, but allowed by C++. There are many other solutions, but the main point is a class hierarchy as we have today is not the best way to make throwable objects being handled differently.

I would like to point out, though, that it is very easy to speak about something that was conceived almost 10 years ago, after many years have passed and after using it and seeing others using it; it's a huge advantage the original creators couldn't have. James Gosling and all the other folks at Sun have made a great job designing Java and its API and, after nearly a decade, it is obvious there are things that could be better. I'll write more about other things - some far more critical than the way exceptions work - soon. Stay tuned!





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