So, I like a Java as a language and I like the whole Virtual Machine thingy. I even dare to say that I like building web apps in Java! Now, everything has limits and JEE sometimes pushes mines just a bit too far.
The thing is Java is growing too much in too many areas. Many people have already started to complain about the number of features (and idioms) in the language itself, probably because Java 7 will bring in some more. I have to say that I was not joining that bandwagon (and I still wait with eagerness the closures support) but I've spent my last three months fighting (there's no better word!) some Enterpise Edition specifications and I'm fed up.
Just take a look at the Java Community Process to get an idea of what is Java today. To me the problem is not the number of technologies or the number of specifications. Nor the fact that Java tries to compete in every possible market niche. I don't mind. The problem is the integration between them! Specially when you group them together and call it a platform.
How can something like JSF be promoted to be the standard? A component framework that lacks even one interesting component! That relies on third party libraries (many OSS) that are, of course, incompatible between them. Each one with a different AJAX approach (as the specification says nothing on the topic). And, worst of all, incompatible with JSP/JSTL and portlet development.
So, if even the Spring people can't get WebFlow to work properly in a JSF + Portlet environment how are we supposed to do so? Do you know that you need to configure JSF RI(or MyFaces) + Facelets(or JSF Templating) + Richfaces(or IceFaces, Tomahawk, WoodStock) + Portlet Bridge(JSR-301 is in draft yet!) + JBOSS EL(you want method invocations right?) just to start developing a page? Can you guess the number of IDEs that support that kind of configuration? Or the number of context-params in web.xml descriptor? Let me assure you something, your first try won't work. Nor the second. From there it will depend if you are mixing something more like say...Spring or, God forbid, WebSphere Portal (or even other EE technologies like JAX-WS or JPA). Can you imagine trying to explain all the gotchas (nightmares actually) to a junior developer???? Or the client????
I'm amazed that some people still have hard times determining why the adoption rate of EJB 3 is still so low (I'm stupidly optimistic and I still have hopes for EJB 3.1...and, yes, JSF 2.0) but I just know that a client side JS framework (choose your destiny!) paired with DWR and a Spring centric backend just happen to work (in a fraction of the time).
domingo 31 de agosto de 2008
martes 19 de agosto de 2008
DWR 3.0 conversion features
So DWR 3 is slated for late September around the Ajax Experience conference (tentative dates, of course) and it's loaded with new features. I've already talked about some of them (like Spring) but right now there's a lot of work being done with converters so I'd like to share some of it a little.
Before, of course, a little explanation to inform clueless people. A converter in DWR is an object that transforms Java to Javascript and vice versa. This is usually transparent to the user as DWR out-of-the-box includes converters for primitive types, arrays, collections, beans and more. Of course, for security reasons not all of these converters are enabled by default and some require a specific declaration (like bean or exception). The conversion procedure is composed of two stages, the inbound conversion that transforms method arguments from JS (using a internal protocol named DWRP) and the outbound conversion of the response (or the method return type).
Advanced users know the use of class mappings as well. These serve two purposes, first they allow a Java to JS object correspondence and (internally) they also add runtime information to each call.
We can look now into the new features 3.0 offers. But first remember (a little disclaimer) that they are currently under heavy work so many are not yet ready but in the working copies of the developers boxes. No more delays, here they are:
Before, of course, a little explanation to inform clueless people. A converter in DWR is an object that transforms Java to Javascript and vice versa. This is usually transparent to the user as DWR out-of-the-box includes converters for primitive types, arrays, collections, beans and more. Of course, for security reasons not all of these converters are enabled by default and some require a specific declaration (like bean or exception). The conversion procedure is composed of two stages, the inbound conversion that transforms method arguments from JS (using a internal protocol named DWRP) and the outbound conversion of the response (or the method return type).
Advanced users know the use of class mappings as well. These serve two purposes, first they allow a Java to JS object correspondence and (internally) they also add runtime information to each call.
We can look now into the new features 3.0 offers. But first remember (a little disclaimer) that they are currently under heavy work so many are not yet ready but in the working copies of the developers boxes. No more delays, here they are:
New converters
An obvious one, more out-of-the-box converters mean less work for each developer. The interest relies in the functionality though. These ones allow file and image transfers using AJAX calls. That is, uploads and downloads using asynchronous calls and progress listeners. Dot syntax support
To date JS objects mapped just the name of the Java class but omitted the package. This has been enhanced to support the fully qualified name. An example that shows hierarchies as well:
Classpath scanning
Before now, each converter required its own declaration. From now on the match clause accepts wildcards to define converters in batch during boot time. They syntax is pretty clear match="foo.*" will locate any class under the foo package while match="foo.bar.**" will, in addition, recurse subfolders. Javascript wildcard expansion
In the same manner as the previous point the javascript attribute of a converter will allow wildcards (both * and **) that will be expanded to the corresponding class name. Thus, * will map to the matched class simple name while ** will be mapped to the fully qualified named (thanks to the dot syntax support). Expect definitions like:
to remote all the classes under the model package (including subpackages) under the JS identifier of foo.bar.<SimpleClassName>. Method overloading
Till today, DWR just politely asked the developer not to overload methods (on the server side). New enhancements in the inbound conversion process allows better identification of the target method and thus overloading. Var args support
3.0 will offer support for Java varargs using JS arrays as the last parameter of a method. Interfaces as method parameters
It will be possible to declare method signatures that include interfaces (or abstract classes) as long as there is at least one converter declared that implements the contract and runtime type information is delivered with the request (class mappings are mandatory). This is an example of why the library prefers DWRP over JSON to transfer data. Separated class mappings
Class mappings are currently defined in every interface file. This leads to duplication and overall worse performance. Next version maintains this behavior for compatibility reasons but adds the possibility to generate class mappings gropued in a external file (to be used with JAWR for example) or just one per file Improved serialization
Next version will detect and avoid the serialization of JS properties that are not mapped in the Java counterpart. Constructor injection
JS classes will be instantiated from a map in addition to the usual setter injection.
And there are some more (like property overriding in conversion) but they may not be ready for 3.0 and will have to wait until the following release.An obvious one, more out-of-the-box converters mean less work for each developer. The interest relies in the functionality though. These ones allow file and image transfers using AJAX calls. That is, uploads and downloads using asynchronous calls and progress listeners. Dot syntax support
To date JS objects mapped just the name of the Java class but omitted the package. This has been enhanced to support the fully qualified name. An example that shows hierarchies as well:
var baz = new foo.bar.BazImpl
...
if (baz instanceof foo.bar.Baz) {..}
...
if (baz instanceof foo.bar.Baz) {..}
Classpath scanning
Before now, each converter required its own declaration. From now on the match clause accepts wildcards to define converters in batch during boot time. They syntax is pretty clear match="foo.*" will locate any class under the foo package while match="foo.bar.**" will, in addition, recurse subfolders. Javascript wildcard expansion
In the same manner as the previous point the javascript attribute of a converter will allow wildcards (both * and **) that will be expanded to the corresponding class name. Thus, * will map to the matched class simple name while ** will be mapped to the fully qualified named (thanks to the dot syntax support). Expect definitions like:
<converter type="bean" match="model.**" javascript="foo.bar.*" />
to remote all the classes under the model package (including subpackages) under the JS identifier of foo.bar.<SimpleClassName>. Method overloading
Till today, DWR just politely asked the developer not to overload methods (on the server side). New enhancements in the inbound conversion process allows better identification of the target method and thus overloading. Var args support
3.0 will offer support for Java varargs using JS arrays as the last parameter of a method. Interfaces as method parameters
It will be possible to declare method signatures that include interfaces (or abstract classes) as long as there is at least one converter declared that implements the contract and runtime type information is delivered with the request (class mappings are mandatory). This is an example of why the library prefers DWRP over JSON to transfer data. Separated class mappings
Class mappings are currently defined in every interface file. This leads to duplication and overall worse performance. Next version maintains this behavior for compatibility reasons but adds the possibility to generate class mappings gropued in a external file (to be used with JAWR for example) or just one per file Improved serialization
Next version will detect and avoid the serialization of JS properties that are not mapped in the Java counterpart. Constructor injection
JS classes will be instantiated from a map in addition to the usual setter injection.
Publicado por Jose Noheda en 23:23 2 comentarios ![]()
miércoles 13 de agosto de 2008
Technical Reading
August is a good month to practice some reading, even more so if, as is my case, you have to stay at work. Between novels and Terry Pratchet I always try to drop in a technical book or two. This summer I finally had the time for two that had been sitting on my TODO list for ages: Java Puzzlers and Effective Java (2nd ed). Both from Joshua Bloch, one of the fathers of Java.
Java Puzzlers is a book that deals (as the name implies) with traps, pitfalls and corner cases. And good practices! An example can clarify things. Look at the following code snippet (taken from puzzle #1):
Java Puzzlers is a book that deals (as the name implies) with traps, pitfalls and corner cases. And good practices! An example can clarify things. Look at the following code snippet (taken from puzzle #1):
public boolean isOdd(int i) {
return i % 2 == 1;
}
return i % 2 == 1;
}
A quick glance reveals a standard use of the modulus to determine if a number is even or odd. Can you spot the problem? I didn't really. In fact, the code does not work for negative odd numbers or rephrased it the method fails in a 25% of the situations. You can test it (I recommend using the Groovy console for testing quick scripts like this). A correct version would look like:
public static boolean isOdd(int i) {
return i % 2 != 0;
}
return i % 2 != 0;
}
The author explains concisely why it fails even proposes a better (faster) version (using the logical AND operator). The book is made of nearly one hundred puzzles grouped in ten chapters covering operators, casting, exceptions, loops, classes et al. The cases are sometimes very convoluted and well beyond the scope of day to day coding but are also important to know. If anything, the book will just make the reader aware of the importance of unit testing and code coverage (although it doesn't mention them explicitly). Even one liners like the above must be matched by a test.
Effective Java is a book on advanced Java programming. You may think that I (or you) don't need a book on the topic any longer. In the end, we are expert coders! Great! Read the book and tell me :-) IMHO this is the definitive Java guide. I was impressed (and probably you will be also) by the depth of the knowledge showed in every chapter. Even those that deal with commodity topics (and this is subjective) like exceptions or some Java 5 features. There's a sample chapter (generics) available for free reading here. You get the idea. Now imagine equal dissertations over Serializable, Concurrency, Composition or Performance. I bet most people don't know the subtleties of the static reserved word and how it interacts with several other language features like, say, private inner classes. If you want to go to that level of depth this is your book.
All in all, I liked both books, though the second is way more useful. Probably they're not as easy to read as something like The Mythical Man-Month or The Pragmatic Programmer but they also offer an understanding of the Java language that you won't get in any other place. So...highly recommended lecture!!
Effective Java is a book on advanced Java programming. You may think that I (or you) don't need a book on the topic any longer. In the end, we are expert coders! Great! Read the book and tell me :-) IMHO this is the definitive Java guide. I was impressed (and probably you will be also) by the depth of the knowledge showed in every chapter. Even those that deal with commodity topics (and this is subjective) like exceptions or some Java 5 features. There's a sample chapter (generics) available for free reading here. You get the idea. Now imagine equal dissertations over Serializable, Concurrency, Composition or Performance. I bet most people don't know the subtleties of the static reserved word and how it interacts with several other language features like, say, private inner classes. If you want to go to that level of depth this is your book.
All in all, I liked both books, though the second is way more useful. Probably they're not as easy to read as something like The Mythical Man-Month or The Pragmatic Programmer but they also offer an understanding of the Java language that you won't get in any other place. So...highly recommended lecture!!
Publicado por Jose Noheda en 23:26 0 comentarios ![]()
martes 5 de agosto de 2008
Joining the FishCAT program
I've been invited by the Glassfish team to join FishCAT, the GlassFish Community Acceptance Testing program. The main goal there will be to test in depth the new modular version of Glassfish 3, called Prelude.
As a long standing Glassfish user (I have to admit I joined the community with the first v2 betas) I'm quite happy to be of help. I'll be testing thoroughly the Web Tier (JEE5, AJAX), part of the business tier (at least JPA), the Netbeans plug-in and Groovy. Of course, that's a lot of work but I'll try to touch everything.
The program is scheduled from August to September 2008 (about four weeks) and it's open to everybody, just need to fulfill a simple registration form. I encourage everybody interested (probably all Netbeans/Glassfish users) to take the step and join the effort. Glassfish 3 looks promising and here's your chance to contribute!
As a long standing Glassfish user (I have to admit I joined the community with the first v2 betas) I'm quite happy to be of help. I'll be testing thoroughly the Web Tier (JEE5, AJAX), part of the business tier (at least JPA), the Netbeans plug-in and Groovy. Of course, that's a lot of work but I'll try to touch everything.
The program is scheduled from August to September 2008 (about four weeks) and it's open to everybody, just need to fulfill a simple registration form. I encourage everybody interested (probably all Netbeans/Glassfish users) to take the step and join the effort. Glassfish 3 looks promising and here's your chance to contribute!
Publicado por Jose Noheda en 9:29 0 comentarios ![]()
jueves 31 de julio de 2008
Sharing a property resolver between Spring contexts
A PropertyPlaceholderConfigurer is a well known tool in the Spring arena. It allows to externalize usually the most changing values of a given configuration to Java Properties files. In fact, Spring offers out-of-the-box implementations that can resolve property values from files, system properties, env properties or even web.xml context params. In addition, it's easy to create extensions to retrieve values from JNDI or database. For example, use the JNDITemplate to access the context and lookup properties:
public String resolveProperty(String property) {
String value = null;
try {
value = (String) jndi.lookup("java:comp/env/" + property);
} catch(Exception e) {
try {
value = (String) jndi.lookup(property);
} catch(Exception ex) {}
}
return value;
}
String value = null;
try {
value = (String) jndi.lookup("java:comp/env/" + property);
} catch(Exception e) {
try {
value = (String) jndi.lookup(property);
} catch(Exception ex) {}
}
return value;
}
The thing is once you have built your uber resolver chances are it will be used across all the different contexts. Unfortunately, even though the bean is inherited, BeanFactoryPostProcessors (and the PPC is one) are tightly coupled to the context where they're defined and won't do their magic in the outside world.
As a little side note, a bean factory postprocessor is a special kind of bean defined in an application context that is initialized and executed before any other bean. They can influence the behavior of the context loading. In our case it's modifying the declarations changing ${...} by an actual value. Of course, they're by definition closely coupled to Spring's life cycle.
So in Spring not being able to inherit PropertyPlaceholderConfigurers is considered a feature and it's by design. If you share a different vision and, for example, would like to share the same resolver between the contexts loaded by the ContextloaderListener and the DispatcherServlet, the good news is it can be done. We have to thank you Spring's configurability and the number of extension point it provides.
We will need two of them, the first is offered by DispatcherServlet and the second by ConfigurableListableBeanFactory. the servlet allow us (extending the class) to override the
As a little side note, a bean factory postprocessor is a special kind of bean defined in an application context that is initialized and executed before any other bean. They can influence the behavior of the context loading. In our case it's modifying the declarations changing ${...} by an actual value. Of course, they're by definition closely coupled to Spring's life cycle.
So in Spring not being able to inherit PropertyPlaceholderConfigurers is considered a feature and it's by design. If you share a different vision and, for example, would like to share the same resolver between the contexts loaded by the ContextloaderListener and the DispatcherServlet, the good news is it can be done. We have to thank you Spring's configurability and the number of extension point it provides.
We will need two of them, the first is offered by DispatcherServlet and the second by ConfigurableListableBeanFactory. the servlet allow us (extending the class) to override the
void postProcessWebApplicationContext(ConfigurableWebApplicationContext wac);
method. This gives us a handler executed before the context is loaded (refreshed) for the first time. And it also gives us a reference to the context itself. In this situation we could add a new bean to this context easily but, better yet, we have a method to add a bean factory post-processor directly. The code is trivial, just get the previously defined bean from the (parent) context and add it. I'm using an anonymous inner class but it's not mandatory really.
wac.addBeanFactoryPostProcessor(new BeanFactoryPostProcessor() {
public void postProcessBeanFactory(...beanFactory) throws ... {
BeanFactoryPostProcessor resolver = beanFactory.getBean("resolver");
resolver.postProcessBeanFactory(beanFactory);
}
});
public void postProcessBeanFactory(...beanFactory) throws ... {
BeanFactoryPostProcessor resolver = beanFactory.getBean("resolver");
resolver.postProcessBeanFactory(beanFactory);
}
});
Basically that's all, change the web.xml (to point to the new class), remove the now redundant beans in the configuration files and redeploy.
Publicado por Jose Noheda en 0:42 0 comentarios ![]()
miércoles 23 de julio de 2008
Invoking Web Services via Spring
SOA SOA SOA...SOA everywhere. Right now it's difficult to work on an enterprise project and don't have the need to connect to a WebService. What would we be without these buzzwords...?
Unfortunately, for us developers that is, WebServices is not the easiest of technologies (understandable as the problem it solves is also complex) and Java's approach has always been guilty of not been the most intuitive. But the need is there so it has to be solved.
To call a Web Service there are several possibilities at the framework level. The first is to use JAX-RPC but this approach is in disuse today (for uber complexity). If we stick to the standard the next API would be JAX-WS. This is a much more polished API based heavily on annotations. JAX-WS is now part of the standard Java Standard Edition. Finally there are other alternatives in the Open Source scene. And better, Spring, in some form or another, supports all of them (Groovy also helps but not everybody has access to it).
It's important to notice that a developer has two ways to connect to a WS (I'll start talking about JAX-WS from now on), creating a SEI (Service Endpoint Interface) proxy or creating and sending a SOAP message. The first case allows the programmer to create a Java interface (mainly because actually it has to be annotated) and forget about the stub. The second (more powerful) alternative creates an XML structure from scratch. Spring facilitates the work with proxies. The later case requires the Spring Web Services subproject.
So how does Spring help? In two ways, it dynamically creates the proxy and injects it to the business beans seamlessly. For the most advanced use Spring, as of now, still requires the Java interface to be provided. All in all, it's not a big deal as there's a tool (wsimport) to generate it given a WSDL. Any good IDE will do it as well. Actually, wsimport generates more than one Java source because the parameters probably require a JAXB (read Java to XML) transformation.
I haven't talked about registries yet. JAXR is the Java API to connect to WSDL containers. They basically provide a level of indirection to a WSDL. JAXR is complicated (to some extent) and if possible I like the REST API better (but not all registries provide it!). IBM Service Registry does, for example (so you can just use Dom4J with some security). Anyway, JaxWsPortProxyFactoryBean (with minor tweaks) supports this kind of access.
That should be all for the gross of the situations. Recall that JAX-WS supports WS-I Basic Profile, MTOM and other such advanced protocols by default. That's not true for all of them though! For example, it requires some work to allow for message level security. This is overcome by the use of LogicalHandlers or SOAPHandlers (you can mix and match). In Spring or AOP jargon they would be called interceptors. They allow to modify the message prior to being wired. Another common and interesting use, for example, is logging. Spring allows handler injection grouped as HandlerResolvers.
So here's the final code:
Unfortunately, for us developers that is, WebServices is not the easiest of technologies (understandable as the problem it solves is also complex) and Java's approach has always been guilty of not been the most intuitive. But the need is there so it has to be solved.
To call a Web Service there are several possibilities at the framework level. The first is to use JAX-RPC but this approach is in disuse today (for uber complexity). If we stick to the standard the next API would be JAX-WS. This is a much more polished API based heavily on annotations. JAX-WS is now part of the standard Java Standard Edition. Finally there are other alternatives in the Open Source scene. And better, Spring, in some form or another, supports all of them (Groovy also helps but not everybody has access to it).
It's important to notice that a developer has two ways to connect to a WS (I'll start talking about JAX-WS from now on), creating a SEI (Service Endpoint Interface) proxy or creating and sending a SOAP message. The first case allows the programmer to create a Java interface (mainly because actually it has to be annotated) and forget about the stub. The second (more powerful) alternative creates an XML structure from scratch. Spring facilitates the work with proxies. The later case requires the Spring Web Services subproject.
So how does Spring help? In two ways, it dynamically creates the proxy and injects it to the business beans seamlessly. For the most advanced use Spring, as of now, still requires the Java interface to be provided. All in all, it's not a big deal as there's a tool (wsimport) to generate it given a WSDL. Any good IDE will do it as well. Actually, wsimport generates more than one Java source because the parameters probably require a JAXB (read Java to XML) transformation.
I haven't talked about registries yet. JAXR is the Java API to connect to WSDL containers. They basically provide a level of indirection to a WSDL. JAXR is complicated (to some extent) and if possible I like the REST API better (but not all registries provide it!). IBM Service Registry does, for example (so you can just use Dom4J with some security). Anyway, JaxWsPortProxyFactoryBean (with minor tweaks) supports this kind of access.
That should be all for the gross of the situations. Recall that JAX-WS supports WS-I Basic Profile, MTOM and other such advanced protocols by default. That's not true for all of them though! For example, it requires some work to allow for message level security. This is overcome by the use of LogicalHandlers or SOAPHandlers (you can mix and match). In Spring or AOP jargon they would be called interceptors. They allow to modify the message prior to being wired. Another common and interesting use, for example, is logging. Spring allows handler injection grouped as HandlerResolvers.
So here's the final code:
<bean id="loggingHandler" class="mypkg.LoggingHandler" />
<bean id="defaultHandlerResolver" class="mypkg.ConfiguredHandlerResolver">
<property name="handlers">
<list>
<ref bean="loggingHandler" />
</list>
</property>
</bean>
<bean id="wsdlRetriever" abstract="true" class="...JaxWsPortProxyFactoryBean">
<property name="lookupServiceOnStartup" value="false" />
<property name="handlerResolver" ref="defaultHandlerResolver" />
</bean>
<bean id="aSample" parent="wsdlRetriever">
<property name="serviceInterface" value="..Sample" />
<property name="wsdlDocumentUrl" value="http://...Sample?wsdl" />
<property name="serviceName" value="Sample" />
<property name="portName" value="SampleSOAP" />
<property name="namespaceUri" value="..." />
</bean>
<bean id="defaultHandlerResolver" class="mypkg.ConfiguredHandlerResolver">
<property name="handlers">
<list>
<ref bean="loggingHandler" />
</list>
</property>
</bean>
<bean id="wsdlRetriever" abstract="true" class="...JaxWsPortProxyFactoryBean">
<property name="lookupServiceOnStartup" value="false" />
<property name="handlerResolver" ref="defaultHandlerResolver" />
</bean>
<bean id="aSample" parent="wsdlRetriever">
<property name="serviceInterface" value="..Sample" />
<property name="wsdlDocumentUrl" value="http://...Sample?wsdl" />
<property name="serviceName" value="Sample" />
<property name="portName" value="SampleSOAP" />
<property name="namespaceUri" value="..." />
</bean>
Get the logging handler source code along a good explanation from here.
Publicado por Jose Noheda en 10:30 2 comentarios ![]()
martes 8 de julio de 2008
Working with DWR sources
By now there's no doubt inside the software industry that the Open Source movement is here to stay. And the most valuable asset it provides is *hint* full access to the source code! And it's a shame that not that many people share this perception as for the majority of developers OSS just means free (read gratis) software.
Of course, being free (gratis) is handy characteristic but it should not be one that bothers much to the gross of us, as we work for companies that can afford it anyway. On the contrary, source code should be of interest for you. Let me just list some of the most useful perks:
Our first task is gaining access to the source code. DWR as many other projects stores the code in a repository. Beware that repositories are not like open wikis and people have different access rights. Anonymous access is the best we can hope for by now. There are many different server types (SCM), DWR has used CVS in the past but right now uses Subversion. We need to have a client installed to access a SVN repository and I can recommend Tortoise.
The repository is available at http://svn.directwebremoting.org/dwr/. It's huge as it includes all the versions ever released so it's probably better to point to the trunk folder (the latest code is available there) or, may be, branches/Branch_2_0/ (where the the code for the previous version lies).
To download the code to our machine we use the checkout command. The export command can be an option if there's no interest in having later updates. DWR has a page with detailed explanations for this step at their site.
Once we have it there we can explore it a little bit further. There are three important subfolders: core (DWR), serverside (different plugins) and ui (client side code).
There's also there a folder named etc that contains project files for different IDEs (netbeans, eclipse, IDEA). Opening DWR inside an IDE is as easy as navigating to the correct folder and opening the matching project. Opening the project in an IDE has the added benefit of allowing quick debugging of changes and their influence in your application.
Alternatively, DWR can be compiled using Ant (by just typing ant at the top of the hierarchy!). Regardless of the method, the compiled classes are always put in the (automatically) created target folder.
Some projects have an extensive documentation available. DWR does not particularly shine in this area (intentionally many times!) but, at least, things are organized so finding something should be manageable. For example, all the Spring integration classes are available inside the serverside/spring folder and are bound to just one package.
And that's all basically. Some simple steps that have configured DWR inside your workspace and facilitate your development needs. And once it's there nothing prevents you to dive a little and improve the tool ;-)
Happy hacking!
Of course, being free (gratis) is handy characteristic but it should not be one that bothers much to the gross of us, as we work for companies that can afford it anyway. On the contrary, source code should be of interest for you. Let me just list some of the most useful perks:
It enables debugging
Otherwise it becomes a blind and unproductive task. And believe me, the time spent debugging will be worth it. It's the best learning tool any programmer can access
It's code written by very proficient hackers revolving common but hard to solve problems. It allows customizations
And I include bug fixes here! It makes you part of a community
Share your code, discuss problems, hear other viewpoints, propose solutions et al!
IMHO fear is the main reason that prevents many programmers to contribute to the scene. But if you're by now convinced of the utility let me demystify the myths! Just follow with me this step by step tutorial to work with DWR source code :-)Otherwise it becomes a blind and unproductive task. And believe me, the time spent debugging will be worth it. It's the best learning tool any programmer can access
It's code written by very proficient hackers revolving common but hard to solve problems. It allows customizations
And I include bug fixes here! It makes you part of a community
Share your code, discuss problems, hear other viewpoints, propose solutions et al!
Our first task is gaining access to the source code. DWR as many other projects stores the code in a repository. Beware that repositories are not like open wikis and people have different access rights. Anonymous access is the best we can hope for by now. There are many different server types (SCM), DWR has used CVS in the past but right now uses Subversion. We need to have a client installed to access a SVN repository and I can recommend Tortoise.
The repository is available at http://svn.directwebremoting.org/dwr/. It's huge as it includes all the versions ever released so it's probably better to point to the trunk folder (the latest code is available there) or, may be, branches/Branch_2_0/ (where the the code for the previous version lies).
To download the code to our machine we use the checkout command. The export command can be an option if there's no interest in having later updates. DWR has a page with detailed explanations for this step at their site.
Once we have it there we can explore it a little bit further. There are three important subfolders: core (DWR), serverside (different plugins) and ui (client side code).
There's also there a folder named etc that contains project files for different IDEs (netbeans, eclipse, IDEA). Opening DWR inside an IDE is as easy as navigating to the correct folder and opening the matching project. Opening the project in an IDE has the added benefit of allowing quick debugging of changes and their influence in your application.
Alternatively, DWR can be compiled using Ant (by just typing ant at the top of the hierarchy!). Regardless of the method, the compiled classes are always put in the (automatically) created target folder.
Some projects have an extensive documentation available. DWR does not particularly shine in this area (intentionally many times!) but, at least, things are organized so finding something should be manageable. For example, all the Spring integration classes are available inside the serverside/spring folder and are bound to just one package.
And that's all basically. Some simple steps that have configured DWR inside your workspace and facilitate your development needs. And once it's there nothing prevents you to dive a little and improve the tool ;-)
Happy hacking!
Publicado por Jose Noheda en 5:13 0 comentarios ![]()
Etiquetas: dwr sources
Suscribirse a: Entradas (Atom)

