|
|
||
Michael Nascimento Santos's BlogJ2SE ArchivesMaking your components work nicer inside MatissePosted by mister__m on February 20, 2008 at 07:20 AM | Permalink | Comments (4)A co-worker had been developing some nice-looking custom components for a customer project. It was tightly integrated with the backend logic, though, so he tried to use it with Matisse, there were several issues, from class loading errors to slowness, since the component was trying to do its "real task" inside the designer. So, when he told me that, I immediately recalled a trick I came to know way back in 1999, while I was struggling with Java and Swing for the first time. The He changed the component constructor to check for design time and skip the "black magic" section. It worked like a charm and he said it was the best tip I gave him last year. So now I've finally had the time to blog again, I thought it would be an interesting tip to share :-) Desktop development made easier with genesisPosted by mister__m on June 21, 2007 at 02:43 PM | Permalink | Comments (4)It's been quite a while since the last time I mentioned genesis here. One of the reasons is I've been working on it a lot and there isn't much time left to blog about it. Hopefully I will be able to do so more often. We have just released genesis 3.0 after almost two years and a half of development. genesis is all about making the development of enterprise desktop applications easier. To accomplish that, genesis provides UI-related features and also a neat way of building and integrating with the back-end of your application. For now, let's focus on the desktop itself. genesis 3.0 comes with full support for Swing, SWT and Thinlet. It supports binding, validation, actions and conditions. Let us say that for the desktop it tries to address nearly the same problem space as JSR-295 (Beans Binding), JSR-296 (Swing Application Framework) First, genesis works with an UI model, instead of plain binding. This means your JavaBean represents the UI data plus the presentation logic behind it. It makes your presentation logic UI toolkit-independent, testable and self-contained. It also doesn't require PropertyChangeListeners at all. Consider the most basic binding example in genesis docs:
If you were to do the same with JSRs 295 and 296, you would have to create a JavaBean with PropertyChangeListener support, fire property changes on setters and also create two genesis also comes with some unique features of its own, such as declarative conditions. Let's analyze the classic dependent comboboxes issue: whenever the selected country changes, the state list should be reloaded. Here is what it takes to implement this with genesis:
So genesis will automatically invoke the There are many other features and things to explore and I hope I can show them here in the next few days. The Brazilian Portuguese users list is quite active these days and there is of course an English users list. Check out genesis and let me know what you think.
Final JavaOne reportPosted 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 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 " 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)! A public pledge to NetBeansPosted by mister__m on May 07, 2007 at 04:55 PM | Permalink | Comments (8)I could not be more disappointed after attending the Swing GUI Building With Matisse: Chapter II presented at NetBeans. It's not a problem with the Swing Application Framework or the NetBeans tooling; it's a problem with freedom of choice, vendor lock-in and a close-minded approach, not community-like friendly by the NetBeans guys. I hate to make such issues public, but I've been trying to solve this in a civilized way for a year. Almost two years ago I've filed an issue about making Matisse extensible. It was ignored for a long time, but over time, I become hopeful again since the NetBeans roadmap indicated that Matisse would support binding for NB 6. Over six months ago, I've emailed Tomas Pavek, the NetBeans Matisse lead developer (as far as I know) and Scott Violet, who was the spec lead for JSR-295, Beans Binding, to make sure Matisse implemented it as an abstraction, so it was possible to use Matisse with other binding technologies, such as JGoodies Binding or genesis. This email resulted in a thread in which I explained to Tomas what was needed in the API in order to support other frameworks (basically, abstracting how you interact with the binding "metadata"/API and providing extension points to generate the specific binding API code). One thing that limited my analysis before was the fact there was no publicly accessible code for JSR-295 or the NetBeans support and I was told that a public preview would be available in January. Well, as most of you know, it has only been made available a couple of days ago. Today, during the session, I mentioned that while I actually found the tooling fantastic, many folks (just for an example, read this) have all kind of issues with Beans Binding and whether NetBeans would allow its users to work with other binding frameworks, by providing a API that is extensible. While Shannon Hickey, the new JSR-295 spec lead, understood it's not like I'm bashing his work, the NetBeans guys simply said they just want to support the standard. What does it mean to you?
Obviously, the first answer would be: "hey, but about maintainance?" but no one is asking for a JGoodies or a genesis binding module to become part of NetBeans; I am just asking for the possibility of doing so if needed without branching Matisse. And, heck, I've read Matisse's code: the kind of support I'm asking for would require just a few days to extract the dependencies and create an abstraction based on interfaces and going through the API review process, that would allow people with enough knowledge about other binding solutions to validate it. That is it. So, to sum up, what I'm complaining about here:
Here is my request: show me I am wrong. Show you can listen to the community. Show me freedom of choice is not just some marketing rubbish. Please. Displaying messages in the system trayPosted by mister__m on February 15, 2007 at 03:56 AM | Permalink | Comments (8)Many folks are aware that Java SE 6 comes with the new Here is the code:
When you run this sample, an hard-drive icon (borrowed from Swing's Metal L&F) will be displayed in the system tray. If you place the mouse over it for a few seconds, the The cool thing is that approximately 3 seconds after the icon appears, a warning message will pop up in your system tray - and if you are running Windows and hide the task bar, it will even become immediately visible. This feature can be quite useful for some scenario, such as monitoring applications. There are several other hidden gems in Java SE 6. Let's keep on searching for them... It's high time: a Date and Time API for the Java SE PlatformPosted by mister__m on February 09, 2007 at 08:59 AM | Permalink | Comments (7)A few times in the past I've considered writing a blog entry summing up all the problems with Date, Calendar, TimeZone, DST rules and other JDK related classes. If you think these APIs are simple, functional and do not cause any harm, believe me, you really haven't done anything trivial with dates. Besides the classic "days are 1-based, month are 0-based" issues and the lack of many major concepts, such as date without time, any date/time calculation fails miserably when it includes a DST start or end date. There are simply too many issues with the current API to list here. However, the point of this entry is not to bash the current Java SE API, but rather to talk about JSR-310: Date and Time API. As stated in the JSR, it "will provide a new and improved date and time API for Java. The main goal is to build upon the lessons learned from the first two APIs (Date and Calendar) in Java SE, providing a more advanced and comprehensive model for date and time manipulation." Our main inspiration will be Joda-Time, a great open-source library originally created by Stephen Colebourne (who will be co-leading the JSR), that you should definitely use today to deal with date and time. We won't simply rename Joda-Time and bless it with the JCP approval stamp. We actually want to learn from it, use Java SE 5 features to design an easier-to-use API, remove all deprecated, complex and not mature enough features and also consider addressing a few issues currently not solved by it. If you want to help us, join the jsr-310 java.net project and subscribe to the mailing lists. If you think you are an expert on the matter, consider joining the expert group. We intend to run this JSR as transparently as possible though, so your voice will be heard even if you just join the java.net project.
Measuring the size of your objects reloadedPosted by mister__m on January 12, 2007 at 10:56 AM | Permalink | Comments (2)The requirements for defining an agent using the So, here are the steps to build a working agent capable of computing the size of your objects. First, let's create the agent class:
One requirement for an agent that is started with the JVM is to have a Now, the main change made to agent definition is that an agent must be packaged on a jar and must be identified by a manifest attribute,
Once you build your project, your agent will be properly packaged and ready to be used. To load it, though, you need to use the
That is it. Running the sample in my machine produces: Size of Object: 8 Size of direct subclass: 8 Size of String "size": 24 Size of Calendar: 112 As a final note, agents are actually intended to allow your code to redefine classes by replace sections of their bytecode as desired. This technique is used by AspectWerkz and AspectJ, for instance, and can also be used for special tasks, such as enabling/disabling specific monitoring, for instance. The object size calculation capability is there, but it is not its main purpose. PS: genesis has been the most active project in December. 3.0 RC1 should be out in a few days. First Java SE 6 bug!Posted by mister__m on January 11, 2007 at 04:13 PM | Permalink | Comments (1)As genesis 3.0 is approaching Release Candidate, I decided to test it using the newly released Java SE 6. I ran the test suite and a single test failed, one involving script evaluation (I've blogged about genesis script support almost two years ago). Since JSR-223 was about to become part of Java SE 6, we've added support for it six months ago. By that time, either the test worked or it hadn't been written yet, but the genesis useradmin sample was running flawless. Well, I've filed a bug in genesis issue tracker and after some investigation, narrowed the problem to its real cause. Basically, you cannot invoke a static method that overloads an instance method using variable.method(arg0, arg1). The following test case demonstrates the problem:
This test output should be something like:
it actually is:test.FunctionsClass@14a9972 true true If you can change the script or the class being called, it is easy to work around this issue (by invoking the method on the class itself with, renaming it or rewriting it to become an instance method). However, if you cannot, you better use Rhino directly. When I run the same test using BSF over Rhino, it works. For future reference, this has been filed as bug # 6512123 (it might take one or two days for it to show up). Let's hope the fix make it to Java SE 6 Update 1. :-)test.FunctionsClass@14a9972 true Exception in thread "main" javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: Can't find method java.lang.Object.equals(string,string). ( Swing made easy with genesisPosted by mister__m on August 25, 2006 at 10:43 AM | Permalink | Comments (13)Swing was always known as a powerful, highly configurable UI toolkit. However, not much longer after it was born, it was also regarded as a slow, hard to learn, confusing, hard to program toolkit. Sun first started working on performance and Swing became faster and lighter - if you only knew how to code make a GUI with it. Designing some interfaces could take hours (or days) and since there are many ways of accomplishing (almost) the same thing in Swing, developers would usually get confused or pick the wrong road. Visual designers such as VEP and later Matisse came and made it simple to design the GUI. However, working with Swing still required understanding models, writing listeners and dealing with the many choices offered by the API. An easier programming model was needed and then binding frameworks started to appear. genesis was born two years ago and it has been supporting GUI-toolkit independent binding for more than a year and a half now. At first, only Thinlet was supported and we were always asked about when it would support Swing. Well, since the beginning of the year a Swing binding has been implemented and now it has finally been released. What makes the binding implemented by genesis unique is that it doesn't require you to use any "proprietary" components and it doesn't require you to code listeners (neither in the interface nor the JavaBean). So you can design your interface using Matisse, write your JavaBean class and just use a couple of annotations to bring it to life. Let's see how it works in practice. Let's say we would like to implement a login use case. We could code the UI handling JavaBean, called a form, like this :
And bind it to a Swing UI like this:
So, as this example shows, genesis binds JavaBeans properties to widgets such as Besides that basic binding features, genesis also makes it possible to enable/disable components based on conditions (using To finish the big announcement day, a SWT binding is now in HEAD and should be released in the next few days. So if you are developing a desktop application that uses either Swing, SWT or Thinlet, take a look at genesis. Bitten by the class literal change in TigerPosted by mister__m on August 16, 2006 at 10:02 PM | Permalink | Comments (8)If you are a returning reader, you're probably aware of the enum implementation I wrote for Java 1.4 almost three years ago. Running some Java 1.4 compatible code compiled with Java 5 has just called my attention to a supposedly low impact change that was implemented in Tiger. Since Java 5, a class literal, i.e., an expression such as Let me explain how my enum implementation is affected by this bug so you can understand if this bug might affect your Java 1.4 code. Enum's sole constructor registers the newly created instance's in a few internal
, cache is populated to tell what is the domain for Ok, now that we have a real world example, let's see what worked with Java 1.4 and fails with Tiger and Mustang:
With Java 1.4, it works; with Java 5, you will get Now, to the shocking news: there is no way to tell whether a
will require you to handle an exception that should never been thrown in this situation ( Therefore, I've submitted a RFE to add For now, beware of code that relies on class literal triggering class initialization and hope the ugly workaround above works for you if you cannot avoid it. Tiger and dates don't get alongPosted by mister__m on February 08, 2006 at 09:27 AM | Permalink | Comments (20)Since Java WebStart 1.4 does not work on Linux kernel 2.6, there are many new features in a certain operating system release that are interesting to the customer I am currently working for and some applications they are willing to use require Java 5, we have started testing their main application on Tiger. However, it fails miserably due to two major bugs that have been available since the first day Java 5 was released. First, Then, there is a binary compatibility bug since the first Java 5 release: So, if you deal with Date, Calendar or use Timestamp comparissons in your JDK 1.4 compatible system or even plan to do so in Tiger, hold your breath: wait for Update 7, whenever it comes around. If you have to upgrade to Java 5 by a certain date due to other reasons, you are in big trouble, just like me. Notice I didn't even mention all the daylight saving problems you will have to cope with if you are just interested in dealing with "plain" dates... Unfortunately, the best advice I can give to anyone planning to do even some simple work with dates is to use Joda-Time, a great piece of Apache-licensed open-source software created by Stephen Colebourne. As a JCP member, I have to ask: which companies or individuals is willing to support a JSR to add a Joda-Time based API to Dolphin and solve this mess in a proper manner? Writing applications that can be embedded in IDEsPosted by mister__m on July 27, 2005 at 11:21 AM | Permalink | Comments (1)Well, every time I think I'll be able to blog more often, something happens. So, I will try not to apologize about it and get straight to the point. :-) A cool thing I did recently was to write a set of NetBeans plugins that adds support for Thinlet in the IDE, called ThinNB. One important feature that it provides is a visual editor for Thinlet xml files. In order to implement it, instead of reinventing the wheel, I've decided to base my work on ThinG, a standalone application created by Dirk Möbius that already did that. There were a few changes I had to do it so it could be embedded in NetBeans and that probably would need to be done to most applications if they were to be converted into IDE plugins, so it is worth talking about them. ThinG's code is actually well-written, so I didn't have to refactor it in order to expose a single class to my plugin, but this might not be true for other applications. If you are writing an application that might be used as a plugin in the future, make sure everything is properly encapsulated and that the right methods are exposed through your "main" class (which does not have to be the one with the The changes I did concerned four main areas:
AppearanceIf you are running in embedded mode, there is already a menu bar, a status bar and a toolbar being displayed. It is important these features can be turned off in your application when running in this mode. What I did was to add a Besides that, since many useful status bar messages were generated by ThinG, I wanted those to be shown at NetBeans's status bar. I solved this problem by creating a simple If there were menus or toolbar buttons that needed to be made available to the end user, it would probably be necessary to write some listener interfaces so it was possible to enable/disable them as required. I/O SystemIf you intend to use your application inside an IDE, it is better to think twice before using Fortunately, ThinG didn't use SettingsThere is a decision to be made about sharing settings: do you want both the IDE and the standalone application to share the same settings or to keep them separate? If you pick option one and your application uses the Preferences API, it is quite straightforward to implement it. If you want to follow the second path, you just need to define yet another interface for that purpose. Since I wanted to add a few settings and hide one from the end user, I ended up creating a LoggingI am not sure this is true for other IDEs, but NetBeans has its own API for logging. In order to integrate with it, whether your application use ConclusionThinG is now both a standalone and an embeddable application after a few changes. It shouldn't be hard to use it as a plugin for Eclipse, IDEA or JDeveloper now, for example. I hope the principles I've explained here can help other people out there as well. Supporting script languages in your applicationPosted by mister__m on April 24, 2005 at 01:13 PM | Permalink | Comments (2)It's been over a month since we added generic script support to genesis, but it was such an interesting experience I've actually considered writing this entry part of my TODO list. I've finally managed to do it, so let's go to the main point before you all fall asleep. Since its inception, genesis has been using JXPath in order to allow users to express conditions that controlls when fields are made visible or not, enabled/disabled, cleared, when a method should be called by the framework etc. JXPath is not exactly a script language, but rather a XPath implementation that works on JavaBeans as well. However, since I was particularly familiar with it, expressions written in it were clear and concise, it is possible to invoke arbritary Java methods from expressions and to export custom function libraries, it was very easy to use in our internal framework code, quite performant and had support for compiling expressions it was picked up as the way to express conditions. Although we did like JXPath a lot, there were some reasons we thought it was worth supporting other options:
Since we decided we wanted to support new script languages, we had to come up with a design for that. Basically, instead of using an available abstraction as is, we wanted to make sure there was no performance degradation for our JXPath users and we were already aware of standardization efforts on this area - JSR 223 to be precise - that were not (and still are not) available for use. This motivated us to come up with a more generic design, in package
The reason I said these are general-purpose classes is because there are other classes in this package that are more specific to genesis "business" itself, such as abstract support for genesis functions, but I won't explain these here though. Now, back to the main plot, the next step was to add a JXPath implementation and that is what package The next step was to add support for two popular script languages: BeanShell and JavaScript. Although we could use our own infrastructure to build that, we were looking for a more general way of abstracting the usage of such languages and decided to use an already existing solution for that. BSF, the Bean Scripting Framework, an Apache Jakarta Project, proved to be a good way of plugging these languages into our infrastructure with minimum effort. Our general adapter package for BSF is After we had support for at least 3 languages - we are still not sure how many BSF supported languages will simply work out of the box -, we still wanted to support another language web developers were familiar with. EL, the Expression Language first introduced by JSTL and later adopted by JSP, was chosen. Since EL as defined in package As we started working in an implementation, we were amazed to find out most things we needed were defined in the SPI and not in the implementation itself. It is really rare for "young" specifications to have this level of support at the "standard" level, so I must congratulate the EL folks on that. Implementing package So, it turns out supporting script languages in an application or framework is not a very hard task and it took us a few days to walk through the whole process, which included selecting the languages to support, study their documentation, look for an existing abstraction, modify our build process and a bunch of other tasks. In the future, when JSR-223 becomes final and an open-source implementation becomes available, it will be even easier to support script languages. First draft for Common Annotations is outPosted by mister__m on March 28, 2005 at 12:45 PM | Permalink | Comments (5)The first early draft for JSR-250, Common Annotations for the Java Platform, has been published. There are less than 10 annotations specified in this version, most of them related to security. Although many other annotations will probably be added for the next versions, as part of the expert group I would like to request your feedback. Download the early draft and send us your comments. The best time to change a spec is at its early stages. Don't miss this opportunity. UPDATE: please send your feedback to jsr-250-comments@jcp.org instead of posting a comment to this entry. Thanks! A tricky issue with java.awt.FontPosted by mister__m on March 21, 2005 at 11:40 AM | Permalink | Comments (30)If your code or code you use relies on loading fonts by name, you may face severe limitations when trying to use your application in a different environment than the one you performed your tests. Although many of us are aware of the fact specific fonts may not be installed on a machine, trying to work around this problem may prove to be more difficult as it seems at first. Most code that loads fonts by name use either the The So, how to solve this problem? If you wrote the code or can modify its source, you simply need to rewrite the parts that load a font by name so that they delegate to a method that looks up the instance in a "registry", such as a The long term fix for this issue would be to add a More about Practical AOP and Transparent RemotingPosted 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:
You already cannot assume you should look for 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 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 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 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 EJBsPosted 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:
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 genesis' aspect named net.java.dev.genesis.aspect.EJBCommandExecutionAspect intercepts execution of methods annotated as 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 genesisPosted 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:
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. ;-) Bizarre behaviour in PropertyDescriptorPosted by mister__m on November 29, 2004 at 09:26 AM | Permalink | Comments (6)I've just found out the most bizarre bug I've ever come accross in my 5 years of experience with the Java platform. Let's suppose you have the following code:
Basically there are two JavaBean classes, B1 and B2. B2 extends B1 and override the getter method for property. BizarreBean.main(String[]) just retrieves an array of PropertyDescriptors from B2's BeanInfo instance and then print the read method for property. The output for this will be:
But what happens if a setter is defined for property? If B1 and B2 are changed like this:
Then the output becomes:
What is the logic behind this? None. This is one of the most awkward bugs I've ever found in J2SE. Unless anyone is able to explain in a reasonable way why this is not bug (I seriously doubt anyone will be able to), I'll file a bug report in the bug parade.
AspectWerkz 1.0 RC 1 is outPosted 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. Playing with the Tiger: Measuring the size of your objectsPosted by mister__m on February 05, 2004 at 07:14 PM | Permalink | Comments (4)As I said, I'm back with more on the new JDK 1.5. There is a new package called
import java.lang.instrument.*;
import java.util.*;
public class InstrumentationTest {
private static Instrumentation inst;
public static void premain(String options, Instrumentation inst) {
InstrumentationTest.inst = inst;
System.out.println("options= " + options);
// Get all classes currently loaded by VM
Class[] loaded = inst.getAllLoadedClasses();
// Sort them by name
Arrays.sort(loaded, new Comparator
Save it as javac -source 1.5 InstrumentationTest.java To allow our class to be useful, we have to start the VM using this verbose command: java -ea -javaagent:InstrumentationTest -cp . InstrumentationTest Someone might be asking how it could be useful. As a friend of mine, Bruno Borges, suggested to me, it could give you a good idea if Prevayler is the right tool for your needs. Hope you've enjoyed it. More to come! Playing with the Tiger: Measuring nanosPosted by mister__m on February 05, 2004 at 06:41 PM | Permalink | Comments (10)Ok, sorry for not blogging for so long, but I have to work, date etc. :-D I hope this is the start of a series of small, but informative blog entries about new features available in Tiger, especially the ones a hundred people haven't mentioned before me :-D To begin with, I'll show you how to use the new nanoTime() method in Here's the code:
import static java.lang.System.*;
public class Nano {
public static void main(String[] args) {
long time = 0;
long newTime;
long smaller = 9999999999999L;
for (int i = 0; i < 100000; i++) {
time = nanoTime();
newTime = nanoTime();
smaller = Math.min(smaller, newTime - time);
}
out.println("Smallest nano interval measured: " + smaller);
out.println("Current time millis: " + currentTimeMillis());
out.println("Nano time: " + nanoTime());
}
}
Save it in javac -source 1.5 Nano.java Then run it normally with: java -cp . Nano My results (P4, 1GB RAM, Windows 2000 Pro) are: Smallest nano interval measured: 1116 Current time millis: 1076038988125 Nano time: 8736336585045 This method is intended to be used as a way to measure performance, for instance. Here, I just tried to get its precision in my current box configuration. Please let me know if you get smallest nano intervals in your platform/configuration. See you soon ;-) Things that could be different - Part 1: ExceptionsPosted 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! JXPath to rescue!Posted by mister__m on December 31, 2003 at 07:36 AM | Permalink | Comments (6)Querying a database is no big deal. SQL has been around for a long time and has become the de facto standard for doing that. So has JDBC, even though nowadays it is being used more as the foundation of other solutions and frameworks. But what you do when you have to query objects? Most people wouldn't be able to answer it, really. Three more common ways of querying your objects in Java are custom indexing, OQL and JXPath. This entry is specifically about JXPath. Jakarta Commons JXPath basically defines a simple XPath interpreter that can be applied to general object graphs: POJOs, Maps, Servlet contexts, DOMs and more. XPath is a W3C standard originally conceived for navigating XML nodes, but can be easily applied to Java. Let's see it in action. To ilustrate its use and advantages, we will work with the classical Order problem (Order, LineItem and Product). Let's assume all Orders are stored in a Collection which is a property of our OrderHistory object. What if we wanted to get all the Orders which contained more than 5 CDs? In plain Java:
Collection selectedOrders = new ArrayList();
Order order;
LineItem item;
for (Iterator orders = orderHistory.getOrders().iterator(); orders.hasNext(); ) {
order = (Order)orders.next();
for (final Iterator items = order.getLineItems().iterator(); items.hasNext(); ) {
item = (LineItem)items.next();
if (item.getQuantity() > 5 && item.getProduct().getType().getName().equals("CD")) {
selectedOrders.add(order);
}
}
}
return selectedOrders.iterator();
To avoid being unfair, using 1.5 sintax: Collection With JXPath:
JXPathContext history = JXPathContext.newContext(orderHistory);
return history.iterate("/orders[lineItems[quantity = 5 and product/type/name = 'CD']]");
That is it. As simple as that. JXPath becomes more valuable as your queries become more complex, but I am not going to show an example here. Someone might ask: hey, but when I would like to manipulate objects in memory? There are a lot of occasions, actually. One very common is when you have a small application that needs to persist a small amount of data. If you combine Prevayler - an option to databases, as it keeps everything in memory and performs persistence through serialization and guarantees data integrity - and JXPath, you have a very fast solution with fewer lines of code. Consider using it when you have the chance. As a final note, JXPath has many powerful features, as compiled expressions and variables - similar to PreparedStatements -, pointer, and many more, but you can find more about these by yourself. Go to the above link, download and start using it. The User Manual in the docs is probably the best one for a Apache Project and is highly recommended reading. Try it as soon as you can: you may become addicted to it... Achieving better compression with DeflaterPosted by mister__m on December 26, 2003 at 10:48 AM | Permalink | Comments (4)I've recently been playing more intensively with CVS - I've always used either IDE support for it or any nice GUI client for CVS available - and found out more about GZIP compression than I knew before. That's my main motivation for this post. It's been quite a while - since JDK 1.1, according to javadocs - Java has been providing support for working with ZLIB compression through its API. The package So, getting straight to code, if you want to compress an object you are writing to a stream:
public void writeCompressed(OutputStream os, Object toWrite) throws IOException {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new GZIPOutputStream(os));
oos.writeObject(toWrite);
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException ioe) {
/*
* The day someone gives me a sensible explanation why this method
* throws an exception (as if there was something I could do about it or
* if I cared!), I will be sooooo grateful :-D
*/
ioe.printStackTrace();
}
}
}
Besides the ugly Indeed, Deflater supports compression levels through a method named The problem is that
public void writeCompressed(OutputStream os, Object toWrite) throws IOException {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new GZIPOutputStream(os) {
{
def.setLevel(Deflater.BEST_COMPRESSION);
}
});
oos.writeObject(toWrite);
} finally {
if (oos != null) {
try {
oos.close();
} catch (IOException ioe) {
/*
* The day someone gives me a sensible explanation why this method
* throws an exception (as if there was something I could do about it or
* if I cared!), I will be sooooo grateful :-D
*/
ioe.printStackTrace();
}
}
}
Using If you happen to be using Prevayler and would like to get smaller snapshots, take a look at reusable-components and download the latest version from here. Also, the Building javadoc from J2SDK source codePosted by mister__m on December 25, 2003 at 07:04 AM | Permalink | Comments (8)If you read my last blog entry about J2SDK 1.5 alpha availability, you know you cannot make public comments about. So, with that information in mind, let's move on :-D Suppose you download a J2SDK version from Sun that comes with no documentation at all. Well, all of them come without it, but for most you can get the docs as a separate bundle and install them. Very recently, I downloaded a J2SDK version for which there is no documentation at all. And no, you cannot download it from Sun's site; it is not there. How am I supposed to work with a JDK that has no documentation? At least, I can build javadoc from its source code and it becomes more usable - though not completely, as the new features summary and those sections where concepts are explained and detailed are necessary for a full experience :-D. In case you happen to face the same problem - if you read my blog frequently, there is a chance you are :-D -, here is a sample Ant build script - not the best possible, it's not the point - you may use to build javadoc from source code: That is it, folks! Remember to edit the script so JDK_HOME becomes your real JDK installation home (ex: C:\j2sdk1.4.2_02), JDK_MAJOR_VERSION becomes the major version of the JDK you are using (ex: 1.4, 1.5 ...) and PLATFORM_EXTENSION becomes the extension used by executables in your platform (ex: for Windows, it's exe). And yeah, it consumes a lot of memory. You can change the value -J-Xmx512m as you want, but it didn't work for me with 128mb, for example. It took around 8 minutes to run it in a P4 2.4GHz with 1GB - hey, but I was making normal use of it (4 IM softwares, email client, etc.) BREAKING NEWS: Got Tiger?Posted by mister__m on December 24, 2003 at 04:36 AM | Permalink | Comments (0)I was going to blog about Date and Calendar (and how terrible they are), but these must wait now. Straight to the point: if you want to get J2SDK 1.5.0 alpha, just go to: http://www.javalobby.org/members/j2se15.jsp This is a cooperation between JavaLobby - hey, just became a member 3 weeks ago, after years of Java, can you believe it? - and Sun. This is really a private release, so, you are not allowed to share your opinions about it with anyone except Sun. No, no feedback on this blog or any comments about J2SDK 1.5 alpha are allowed at all. You must be a member of JavaLobby to download it. Are you still reading this??? Go there and download it now! Writing enums before TigerPosted by mister__m on December 10, 2003 at 10:46 PM | Permalink | Comments (12)One thing I've been missing in Java is support for enums. Some of you might be asking: but what is a enum and why should I care about them? A enum is, in a simple way, a class with a limited domain. For example, a class representing the seasons we have during the year - although climate seems crazy these days, anyway, but that's a different story - is a enum. Another example would be a class that represents gender, as it only has two values, male and female (though, again, some might argue it is not that simple :-D). Enums for J2SE 1.5 are being defined by JSR-201. I recommend you read the draft spec when you have the chance, but I'll cite the relevant points as needed. First, let's take a look at the main features both - my implementation and the future J2SDK 1.5 one - share, as specified by the draft spec at the JCP site:
How is it possible to achieve these things now? By using the
import net.java.dev.reusablecomponents.lang.Enum;
public final class Gender extends Enum implements MyInterface {
public static final Gender MALE = new Gender("Male");
public static final Gender FEMALE = new Gender("Female");
private Gender(String name) {
super(name);
}
}
In this example, MyInterface is a simple marker interface that is implemented just to show you it is possible to do so. :-D The code doesn't look that complicated, but it gives you all those things and also these additional features quoted from the JCP spec: All enum classes have high-quality toString, hashCode, and equals methods. All are Serializable, Comparable and effectively final. None are Cloneable. Arbitrary fields may be added to enum classes, and to individual enum constants. To be exact, you have to make your Enum subclasses final. If you subclass an Enum subclass, it simply won't work. However, the greatest feature these Enum subclasses have is that their instances may be compared using the Surely, there are some differences between my Enum and the one provided by the JSR-201. I hope to explain most of them here, but to be sure you understand all the differences, read the spec linked above and browse the most recent version of my Enum implementation. While the J2SE 1.5 enum is intended to give you comparability, it limits the way you naturally compare your instances by making
public enum Gender implements MyInterface {
male, female
}
Although it is by far cleaner than the code I showed above, it requires special compiler features and most IDEs won't support it now. Maybe you could be thinking: but why I need to use a superclass if I can write an enum implementation on without one? Well, you would have to rewrite things you need, such as serialization and Now that I gave you a general idea of what If you are interested enough, I recommend you check the code. You can ask questions and leave your comments below. reusable-components is intended to give you more than that, though; in the next few weeks, I expect to commit some validators for user input and also a cool image generator for use in forms to make sure users aren't frauding your application. Join the project if you want to help. And stay tuned. | ||
|
|