Perfect reprise for the biggest Ape in computing: here. If you haven't seen the YouTube classic Developers, Developers, Developers, spin that first.
74339 items (71032 unread) in 79 feeds
Actualités
(10326 unread)
Informatique
(11372 unread)
Sport & Loisirs
(1300 unread)
Blogs
(1537 unread)
Gwadanina.net
(1271 unread)
Sciences & Techno
(3009 unread)
Antilles Martinique Guadeloupe
(19578 unread)
Open Source & Libre
(3437 unread)
Developpement
(12771 unread)
Sécurité
(3332 unread)
FAI
(619 unread)
Cultures
(258 unread)
Cinéma
(65 unread)
Recettes
(312 unread)
Autres
(78 unread)
Referencement
(283 unread)
Photos
(1452 unread)
Entreprise
(32 unread)
Perfect reprise for the biggest Ape in computing: here. If you haven't seen the YouTube classic Developers, Developers, Developers, spin that first.
/**
|
/**
|
TopCoder says on their site that they were named to Inc. Magazines list of fastest growing companies. What seems to be growing alongside their company is their hubris. They wanted to find a UML tool to use, but couldn't so what do you think they did? They built one, Pal. Step aside. Here it is. (Another early sign of hubris here: they only implemented some of the diagram types, and in a move that defies reason, they did sequence diagrams, but did not add the ability to see the sequence as a collaboration.. but folks, omission is one of the sharpest forms of definition.)
Now, having long flown the flag that the world needed a really good UML tool, I was of course interested. I downloaded and followed the instructions, and what do you know, it doesn't work. No icon appears, and running run.sh gets nothing. Must be because I am on the mac. Announcement, ye of increasing heft: TONS of devs are on macs now. After reading a huge torrent of hyperbole that makes TC seem like the development equivalent of cold fusion (not the templating tinkertoy, the dixie cup sun), it is laughable to push through the first turnstile into an experience that is so fraught with the usual potholes. Here's a clue folks: if yer fusion has platform requirements, get one of the Herculeans to add a short list to the download page, it will make y'all seem a bit less like just another gangway attraction in the Barnumian Universe.
I didn't include code last entry on this subject. Basically, I wanted a really simple abstraction to a select statement so I can:
All of this was written for situations where I have the same basic query over and over again, with slight variations, mostly driven by different user options. It's very similar to what you can do with Hibernate's Criteria object, except I'm dealing with a very thin abstraction over a string rather than a new paradigm.
With out further ado, here's the code:
package builder;
import java.util.*;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* This class represents a select statement.
*
* @author sduskis
*/
public class SearchQuery {
private List select = new ArrayList();
private List from = new ArrayList();
private List where = new ArrayList();
private List order = new ArrayList();
private Map parameters = new HashMap();
public String toString() {
StringBuffer selectString = new StringBuffer();
addSqlString("SELECT ", this.select, ",nt", selectString);
addSqlString("FROM ", this.from, ",nt", selectString);
addSqlString("WHERE ", this.where, "ntand ", selectString);
addSqlString("ORDER BY ", this.order, ",nt", selectString);
return selectString.toString();
}
private StringBuffer addSqlString(String prefix, List list, String delimiter, StringBuffer s) {
if (CollectionUtils.isEmpty(list))
return s;
if (s.length() != 0)
s.append("n");
return s.append(prefix).append(StringUtils.collectionToDelimitedString(list, delimiter));
}
public SearchQuery select(String s) {
return add(select, s);
}
public SearchQuery from(String s) {
return add(from, s);
}
/** add joins to an existing "table */
public SearchQuery appendFrom(String appendStr, int location) {
String fromStr = from.get(location).toString();
fromStr += appendStr;
from.set(location, fromStr);
return this;
}
public SearchQuery where(String s) {
return add(where, s);
}
public SearchQuery orderBy(String s) {
return add(order, s);
}
public SearchQuery parameter(String key, Object param) {
parameters.put(key, param);
return this;
}
private SearchQuery add(List l, Object o) {
if (o != null)
l.add(o);
return this;
}
... GETTERS ...
}
I just screamed at Java again. This time my ire has been raised by the lack of self-types in the language.
Self-typesSo what is a self-type. Well, I could point you at some links, but I'll try and have a go at defining it myself...
A self-type is a special type that always refers to the current class. Its used mostly with generics, and if you've never needed it then you won't understand what a pain it is that it isn't in Java.
Here's my problem to help explain the issue. Consider two immutable classes - ZonedDate and LocalDate - both declaring effectively the same method:
public final class ZonedDate {
ZonedDate withYear(int year) { ... }
}
public final class LocalDate {
LocalDate withYear(int year) { ... }
}
The implementations only differ in the return type. This is essential for immutable classes, as you need the returned instance to be the same type as the original in order to call other methods (like withMonthOfYear).
Now consider that both methods actually contain the same code, and I want to abstract that out into a shared abstract superclass. This is where we get stuck:
public abstract class BaseDate {
BaseDate withYear(int year) { ... }
}
public final class ZonedDate extends BaseDate {
// withYear removed as now in superclass, or is it?
}
public final class LocalDate extends BaseDate {
// withYear removed as now in superclass, or is it?
}
The problem is that we've changed the effect of the method as far as ZonedDate and LocalDate are concerned, because they no longer return the correct type, but now return the type of the superclass.
One solution is to override the abstract implementation in the subclass, just to get the correct return type (via covariance):
public abstract class BaseDate {
BaseDate withYear(int year) { ... }
}
public final class ZonedDate extends BaseDate {
ZonedDate withYear(int year) {
return (ZonedDate) super.withYear(year);
}
}
public final class LocalDate extends BaseDate {
LocalDate withYear(int year) {
return (LocalDate) super.withYear(year);
}
}
What a mess. Imagine doing that for many methods on many subclasses. Its a large amount of pointless boilerplate code for no good reason. What we really want is self-types, with a syntax such as <this>:
public abstract class BaseDate {
<this> withYear(int year);
}
public final class ZonedDate extends BaseDate {
// withYear removed as now correctly in superclass
}
public final class LocalDate extends BaseDate {
// withYear removed as now correctly in superclass
}
The simple device of the self-type means that the withYear method will now appear to have the correct return type in each of the subclasses - LocalDate in LocalDate, ZonedDate in ZonedDate and so on. And without reams of dubious boilerplate.
Self-types are a necessary companion for abstract classes where the subclass is to be immutable (and there are probably other good uses too...).
Opinions welcome as always!
private static class MyObjectListCellRenderer extends DefaultListCellRenderer
{
@Override
public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus )
{
JLabel label = (JLabel)super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
label.setText( ((MyObject)value).getName() );
return label;
}
}
To avoid having to write this, I create a PropertyListCellRenderer (inspired by GlazedList's TableFormat method) that avoids that you need to subclass, you can just create one like this:
ListCellRenderer renderer = new PropertyListCellRenderer( "name",
MyObject.class );
myJList.setCellRenderer( renderer );
This is the code for the PropertyListCellRenderer:
package com.jroller.fester.swing;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
*
*/
public class PropertyListCellRenderer extends DefaultListCellRenderer
{
private static final Logger logger = Logger.getLogger( PropertyListCellRenderer.class );
private final String m_propertyName;
private final Class m_clazz;
/**
* @param propertyName the name of the property you want to be shown in the list
* @param clazz the class of the objects that are in the list model
*/
public PropertyListCellRenderer( String propertyName, Class clazz )
{
m_propertyName = propertyName;
m_clazz = clazz;
}
@Override
public Component getListCellRendererComponent( JList list, Object value, int index, boolean isSelected, boolean cellHasFocus )
{
JLabel label = (JLabel)super.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
try
{
String methodName = "get" + m_propertyName.substring( 0, 1 ).toUpperCase() + m_propertyName.substring( 1 );
Method m = m_clazz.getMethod( methodName );
if (m == null)
{
throw new IllegalArgumentException( "Method '" + methodName + "' could not be found" );
}
if (m_clazz.isAssignableFrom( value.getClass() ))
{
String text = (String)m.invoke( value );
label.setText( text );
}
else
{
throw new IllegalArgumentException( "The value in the list is not of class " + m_clazz.getName() + ", but class " + value.getClass().getName() );
}
}
catch (NoSuchMethodException e)
{
logger.error( e.getMessage(), e );
}
catch (IllegalAccessException e)
{
logger.error( e.getMessage(), e );
}
catch (InvocationTargetException e)
{
logger.error( e.getMessage(), e );
}
return label;
}
}
It is pretty straight forward and using standard Java reflection techniques.
today i lost some time while struggling with a tiny(possibly buggy) case... my case is: put a property in a properties file and use it from an ant build file :)
in fact, it's so easy.. but a tiny issue caused to lose some time of mine... dropping it may help others...
suppose we have property file like this;
modul.properties
|
prop1=val1
|
above property file defines a property, myJarDir, to hold the directory name of may jars...
second, we have an ant build.xml file which includes a task to create a directory with "myJarDir" property's value;
build.xml
|
<project name="sampleAntProject" basedir="." default="make-jar-dir">
|
now, when you run the task you will see that; it will create a folder as "WebContent${myJarDir}" not our expected "WebContentgisjars" folder...
problem is; ant can not see the property from my property file if i load that property file after its usage in another property. To get the correct result, we should load our property file before its usage(above the "mylib-dir" property).
working build.xml should be written like below;
build.xml
|
<project name="sampleAntProject" ................>
|
it's interesting that; if i use "${webcontent-dir}/${myJarDir}" directly at mkdir task, it's working as normal.. This error occurs only if i put "${webcontent-dir}/${myJarDir}" value into another property(mylib-dir) before the loadproperties task and use that property at my mkdir task.
i've googled and looked at ant docs but can not see any information about definition order of properties.. if anyone see a doc explaining property definition order of ant, i'll be glad to read it..
Begin forwarded message:
From: James Gosling
Date: August 24, 2007 8:16:58 PM PDT
To: Jonathan Schwartz
Subject: How was Java named?
The story goes like this:
We needed a name. We had been using "oak" (which was selected
essentially randomly by me), and while the team had grown attached to
it, the trademark lawyers ruled it out. We had lots of email debates
about names, but nothing got resolved. We ended up in the awkward
position where the #1 thing stopping us from shipping was the name.
Our marketing lead knew someone who was a "naming consultant"
(I don't remember his name, but he was great). We could neither afford
the price nor the time of a conventional product naming process. He
agreed to do something rather odd, but effective and quick: he acted as
a facilitator at a meeting where about a dozen of us locked ourselves
in a room for an afternoon. He started asking us questions like "How
does this thing make you feel?" (Excited!) "What else makes you feel
that way?" (Java!) We ended up with a board covered with essentially
random words. Then he put us through a sorting process where we ended
up with a ranking of the names. We ended up with a dozen name
candidates and sent them off to the lawyers: they worked down the list
until they hit one that cleared their search. "Java" was the fourth
name on the list. The first name on the list was "Silk", which I hated
but everyone else liked. My favorite was "Lyric", the third one on the
list, but it didn't pass the lawyers test. I don't remember what the
other candidate names where.
So, who named Java? Marketing organized the meeting, the
consultant ran it, and a whole pile of us did a lot of yelling out of
random words. I'm honestly not real sure who said "Java" first, but I'm
pretty sure it was Mark Opperman.
There certainly wasn't any brilliant marketing mind who went through a coherent thought process.
URL: http://blogs.sun.com/jonathan/entry/better_is_always_different
I will be presenting at JavaZone 2007 in Oslo, Norway September 13-14. JavaZone is one the largest European Java conferences and this is a great opportunity for us to talk about GridGain project and most importantly about the technology and ideas behind it and our view on grid computing in general. I will be presenting on "Java Grid Computing with AOP – Fun, Simple and Productive". In this presentation I will show a live coding example where I will create a simple grid application in just 10-15 minutes. Should be fun!
JavaZone is a must go if you can travel (and if you are in Europe – you are just couple of hours flying away at the most).
So I finally stumbled across the problem that has been plaguing me with my spring/hibernate application. It turns out it was the database's fault. Well, OK, it's not the database's fault. But still ....
The problem was due to the fact that one of the objects was declared having an ID of type String (java.lang.String) and the database column was a CHAR(20) while the data was only of length 16. (Have you figured out what the problem was yet?). Apparently, Hibernate recognizes a difference between "ABCD" and "ABCD ". Once I created a view that wrapped the column in a TRIM(), everything started working beautifully.
So that's the short version of what happened. If your curious about the long version, read on.
I started by alternating between bag and set while moving inverse="true" to either hbm.xml file (thanks for the pointer Eric). No matter what I did, I still couldn't retrieve the List (or Set) of objects; and, to make matters worse, I wasn't getting any error messages. Then I ran across a blog entry that talked about the difference between load and get. I noticed I was using load, so I changed it to get. I also read some blogs about not using the Spring templates and wrappers, so I made my DAO extend HibernateBaseDao and changed my calls to use the HibernateTemplate. Then, wham! I started getting error messages about the ID being changed (or something like that, sorry I don't remember the exact message). Well, if you read my previous entry you'd know that an error message can be a good thing. After a little bit of googling with no luck on a solution, I ran across a forum post describing the issue and mentioning the trailing spaces. Then it occurred to me to try wrapping the column in a TRIM(); and, well, you know the rest. Everything works great now. I can retrieve a List of either object from either side.
All in all, I'd say it was a good learning experience and hopefully someone else who's having similar problems will stumble across my blog and be inspired with an answer to their problems. (If so, please let me know )
java.lang.ClassCastException: org.springframework.context.access.ContextBeanFactoryReference cannot be cast to org.springframework.context.access.ContextBeanFactoryReferenceI assume this is a classloader issue but I'm not yet sure how to solve it. The same jars (versions) are available on the classpath and the webapps are running under a single instance of Tomcat. Any ideas??
As some of you know, I haven't written a single line of Java code since I joined Google in April. I've been working mostly with C++. As usual, you won't find any Google-specific information in this post.
I have always been a fan of Test-driven development. Good unit tests make extensive use of Mock objects, so I am a fan of Dependency Injection as well. In its bare form, where we don't have a magical container that injects dependencies for us, we're talking about DI's origins, Inversion of Control: taking away the control flow of instantiation from inside the classes. Inversion of Control is a technique that helps you enforce the Single Responsibility Principle: the idea that each class should have one and only one purpose, one (small) thing that it's responsible for — and delegate all the rest. In the specific case of instantiation, it also delegates the construction of objects.
For example, if a class uses a special map that you can, say, load and save to a file, but the main responsibility of the class is to process something doing lookups on the map, you can refactor the map code to a separate class, say, SpecialMap, and leave the original class with the processing code, delegating the lookup to SpecialMap. You would then pass the SpecialMap in the constructor, fully initialized and ready for use. In Java, this is peanuts. In C++, it might be hard work, because all classes have one additional responsibility, namely memory management.
// this doesn't work:
MyObject start(const string& param) {
MyDelegate delegate(param);
MyObject obj(delegate);
obj.start();
// return-by-value, this will copy obj
// into another instance!
return obj;
// delegate gets destructed here!
}
In C++, local variables have local scope, and the default behaviour is pass-by-value. This means that object instances are copied around. In the snippet above, two things might happen:
If the former is true, then a new instance of MyObject will be stored in the variable that calls the function start(), thus copying the delegate object a third time! This is hardly ever what you want.
Side note: Java only has pass-by-value. But Java variables are either primitives or references: there are no object variables nor pointer variables. And that's a pretty good reason to provide garbage collection. In 1994, Java was slow not only in the evolutionary sense.
What people do in C++ is allocate the object from the heap using new and write the constructor to receive a pointer to an object:
class MyObject {
public:
MyObject(MyDelegate* delegate);
~MyObject();
private:
MyDelegate* m_delegate;
};
// Now this works:
MyObject* works(const string& param) {
MyDelegate* delegate = new MyDelegate(param);
MyObject* obj = new MyObject(delegate);
obj->start();
return obj;
}
But who's responsible for the deallocation of these objects? To avoid memory leaks, it must be clear to the clients. Anybody instantiating a MyObject should know right away if it's going to delete the delegate when it's gone. Suddenly everybody is busy with lifecycles, because either:
m_delegate, and thus the instance created by the client must live at least as long as MyObject; orm_delegate in its destructor and the MyDelegate instance created by the client can only be used as long as MyObject is aliveSo much for separation of concerns, right? I never thought that adding inversion of control to code would encourage the use of Evil Singletons.
A little research brought me to this post by Michael Feathers where he explains why building a decent DI framework for C++ is so difficult. Add to that that your own code using DI is nothing trivial and I wonder if we're ever going to see the end of the tunnel here.
In practice (and remember, I have only a few months practice, a little more if you count my graduation years), it's easy do choose what's going to happen: either the two lifecycles are completely intertwined, or the two objects have independent lives and it's pretty easy to know who dies first. Two examples:
Example 1: Your code parses some text and does something else with it, the parsing should be delegated to a separate class. But there's no reason for anyone else to reuse the parser, so you explicitly state (by leaving a comment) that your class deletes the parser when it's destroyed.
Example 2: Your code uses a heavyweight object like a GUI toolkit, connection pool, etc. In general, these big, heavy objects are designed to be used by many different objects and have easily recognizable traits (for example, being thread-safe). So you should explicitly state that you don't delete the object when your class is destroyed.
My conclusion is that it's a tough problem, but usually easy to feel what is the right approach. And your answer will also lead you to consider your own class: is it something that clients will want to use in many different objects, or is it more likely that people who delegate to your class will declare local variables of it and/or cascade delete it? And if you really have to do all this thinking, is a DI framework valuable at all?
P.S.: If the Java world had been forced to think about this issue for every class ever to join the API, maybe the StringBuilder would have come out much, much sooner.
I am currently working on a project involving JSF, Facelets and JPA. I had recently downloaded Eclipse Europa, specifically the JDT and WTP. Unfortunately WTP does not include Facelets support by default, but I had read somewhere that RHDS does, therefore I decided to download it and take it for a spin.
In case you have been living in a cave for the last few years, let me give a very brief introduction to Facelets. By default, JSF uses JSP as its view technology, but allows this default view technology to be replaced by an alternative view technology. Facelets is a very popular alternative view technology for JSF. Facelets are usually written using XHTML. XML name spaces are used for JSF specific components.
The standard XML editor that comes with the Eclipse Web Tools project does not offer autocompletion of JSF components when editing XHTML, but the XHTML editor in RHDS does. In my experience, the editor completion worked as expected, the only problem I found was that RHDS would occasionally freeze. Unfortunately it froze frequently enough that I found myself switching to good old Eclipse Europa when working with artifacts other than Facelets, then switching back to RHDS to get Facelets autocompletion.
By the way, even though JBoss is now a Red Hat product, RHDS does not tie you to JBoss, I am, as a matter of fact, deploying the project I'm developing with RHDS to GlassFish without any difficulty.
I received a tentative date in which my new book, Java EE 5 Development With GlassFish Application Server, will be published. Expect to see it in select online and brick and mortar bookstores on or before September 24th.
It will be available on Amazon, BookPool, Borders, and others. Additionally it is currently available for pre-order directly from Packt Publishing.
The book covers all major Java EE APIs including JSF 1.2, EJB 3, JPA, JAX-WS and more. Additionally, frameworks that build on top of Java EE are covered, including Facelets, Seam and Ajax4jsf
After three and half years, I am finally retiring JVending on sourceforge. Over the years, I have uploaded a number of interesting mobile projects under JVending: a JSR-124 implementation (with P2P content sharing), a J2ME MMS client (JDJ Article), J2ME DRM wrapper, a PPG Client and a registry framework for CDC devices.
I have a newer version of my 2001 J2ME GPS client ( JDJ Article) still sitting on my computer that I never uploaded (this newer version was originally for a client that backed out). I also have a fairly complete implementation of the MMI spec (DRM). A good portion of my life went into these projects, but I haven't done a release in over a year.
Since there is no JVending community, with my schedule I can't justify spending more time on development. Looking back, I can see why building a JVending community was so hard: not many people need to setup their own mobile provisioning server; most don't know what a PPG is (even if they had access); and they certainly aren't going to be interested in adding DRM.
My expectation back in 2004 was that a lot of enterprises would start looking for ways to directly enter the mobile content area and this would be JVending's niche. A lot of enterprises did start entering the mobile content area (I got some good consulting gigs out of it), but eventually these companies found that dealing with carriers was such a pain, they started going through aggregators that had pre-existing relationships with the carriers. It's a carrier's market and carriers aren't going to deploy anything without support of a backing company.
JVending is still the only open-source version of JSR-124 that I know of. It hasn't passed a TCK, but if you are interested in poking around the code to see how it works, download the source; feel free to contact me with any questions.
Three weeks ago I blogged about a "Groovy way" to create XML documents in Java. This article now is about a convenient way to access XML without requiring more than a single class (downloadable here) on top of the JRE's own XML library functions.
In fact I wrote this class before I even looked for an easy way to create XML myself, because at the time I just had to parse some XML and extract the values in an easy to use fashion.
I believe it is easiest to show an example of how to use the class. Consider the following very simple Java class:
import java.math.BigDecimal;
/**
* Simple value object for a contact.
*/
public class Contact {
public String firstname;
public String lastname;
public boolean withAccount;
public Integer numberOfCalls;
public BigDecimal amountDue;
}
Usually the fields would not be public of course, but for the sake of the example, just imagine the getters and setters being there ;-)
Now consider getting an XML string back from an external system that you cannot change:
<representative>
<address>
<street>Somewhere</street>
<city>Over The Rainbow</city>
<details>null</details>
</address>
<personal>
<name>Someone</name>
<firstname>Special</firstname>
<age>55</age>
<acct>true</acct>
</personal>
<supportHistory>
<phone>
<total>14</total>
<x11>5</x11>
<x12>9</x12>
</phone>
<incident>
<id>1</id>
<cost>1.50</cost>
</incident>
<incident>
<id>2</id>
<cost>2.50</cost>
</incident>
<incident>
<id>3</id>
<cost>3.50</cost>
</incident>
<incident>
<id>4</id>
<cost>4.50</cost>
</incident>
</supportHistory>
<current>
<due>44.12</due>
<total>100.88</total>
</current>
</representative>
What's the easiest way to get this into the “Contact” class above, without using persistence frameworks, mapping tools and the like? What about this:
XPathAccessor acc = new XPathAccessor(someXML);
Contact contact = new Contact();
contact.firstname = acc.xp("representative", "personal", "firstname");
contact.lastname = acc.xp("representative", "personal", "name");
contact.withAccount = acc.xpBool("representative", "personal", "acct");
contact.numberOfCalls = acc.xpInt("representative", "supportHistory", "phone", "total");
contact.amountDue = acc.xpBD("representative", "current", "due");
I find this rather straightforward. Of course the Strings should be declared as constants somewhere to prevent typos.
The example is really simple, because we just extract some plain values from the XML. However, you have the full power of XPath at your disposal. This means you could do something like this:
BigDecimal getTotalIncidentCost(String someXML) throws SAXException,
IOException, ParserConfigurationException, XPathExpressionException {
XPathAccessor acc = new XPathAccessor(someXML);
BigDecimal tResult;
Node historyNode = acc.getNode("representative", "supportHistory");
tResult = acc.xpBD(historyNode, "sum(incident/cost)");
return tResult;
}
The XPathAccessor instance could (and should) be reused, of course, depending on how often you need to access the document. As it caches XPath expressions that have already been used, it saves some cycles to re-use it for all accesses to a particular document.
Getting the “historyNode” first is of course not really necessary in this simple case, however sometimes it can come in handy to keep the expressions readable when you need to access deeper parts of the XML.
As with the XElement class, feel free to use this one, too. I would be happy to get feedback and/or improvements.
<bean id="openEntityInView"
class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor">
<property name="entityManagerFactory">
<ref local="cep-webEntityManagerFactory" />
</property>
</bean>
<bean id="handlerMapping"
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openEntityInView" />
</list>
</property>
</bean>
Il SimpleFormController per l‘upload di MagicBox si è abbellito con la barra di stato dell‘ upload
Ricetta :
1 SimpleFormController
1 AbstractController
1 JSP
2 Velocity Template
1 Commons Upload Listener
1 prototype script
css a piacimento
La prossima settimana articolo completo + recensione Spring in Action Second edition
Stay Tuned
Earlier this week, the OpenJPA community released OpenJPA version 1.0. The release is available for download at http://openjpa.apache.org/downloads.html. Read the release notes for more details.
I'd like to thank Marc Prud'hommeaux in particular for all his hard work getting the release built and automating a significant amount of the process.
All that happened in a span less than a minute. Just a short San Francisco minute...
This blog entry is a summary of changes I had to implement in order to migrate some EJB3+web services code to the new platform. From the other side of the webservices we have a C# .NET2.0 client. This is not an official reference, and probably few things that I did are the wrong approach. I was trying to minimize changes to the .NET code and try to stay as close to the standards.
NOTE0: I don't have much time to write this summary, so typos and omissions are possible...
NOTE1: The decision to move to JBossWS2.0.1 was almost arbitrary. I switched to the new version because I hoped that some of the stuff that didn't work right away will work in the new version.
NOTE2: When referring to JBoss4.0.4 I collectively refer to all the libraries that ship with it.
The @EJB annotationJBoss 4.0.4 was released with EJB3 support still in beta. Therefore the @EJB annotation was still in the javax.annotation package. In later releases, including JBoss 4.0.5, it has moved to its final destination in the javax.ejb package. The symptoms of missing this step (and deploying code linked with 4.0.4 on 4.2.x server) : Dependency injection simply doesn't work, and all the "injected" fields are nulls.
Missing constructors/settersJBoss 4.0.4 has allowed classes that participate in webservices (as parameters or return values) to omit the default constructor if the class was never to be constructed by the remote side. In the new version, all such classes must have a default constructors. Additionally, JBoss 4.0.4 has recognized such classes as beans even if a setter was missing (again, if the class was constructed on the Java side). Now I found that all setters must be present, or each getter must be annotated with the @XmlElement annotation.
The WebContext and the web context rootIn JBoss4.0.4, the context root of all the webservices was the file name of their common jar file. For example, if our beans were jarred in a beans.jar file, then the context root would be "/beans" and the webservices can be accessed at [localhost:8080] . This behavior has changed in JBoss4.2.1 (that ships with JBossWS1.2.1) and now each webservices class defines its own context root, which by default is the class name. So if you have 5 classes you end up with 5 different context roots. JBoss doesn't like it and will issue an error at deployment time. The solution is to manually add the JBoss-specific @WebContext annotation to each class, like @WebContext(contextRoot="/beans"). JBossws 2.0.1 uses some kind of compatibility mode, in which there is no need to use the special @WebContext annotation, but the default context root has changed to include the name of the EAR file. So if the beans.jar file is put into a demo.ear file, the context root of the webservices will be [127.0.0.1:8080]. In order to override the new default context, it is possible to use a new annotation @org.jboss.wsf.spi.annotation.WebContext(contextRoot="/beans") on just one of the services.
CapitalizationAnother incompatibility is the way in which the parameter classes are named in the WSDL and therefore in the .NET client. For example, if in 4.0.4 I had a webservice that looks like
@Stateless
@WebService
public class TestClass2 {
@WebMethod
public MyClass getMyClass() {
return new MySubClass();
}
}
The "MyClass" identified would appear in the WSDL as "MyClass". In newer versions, it is decapitalized to begin with a lowercase letter: "myClass". It breaks the existing .NET code, so I had to manually add the @XmlType(name="MyClass") annotation to the MyClass definition (and to the few dozens of classes that I used).
Passing webservice method parametersOne of the most significant changed in the new webserives implementation is the way it passes parameters and return value of primitive wrapper types (Integer, Long). Previously, such parameters would be defined in the WSDL as "nillable" and the corresponding .NET definition would represent them as .NET nullable types (e.g, "int?"). In the new webservices library, such parameters are given the maxOccurs="0" attribute in the WSDL and therefore appear in .NET as a pair of "int param" and "bool paramSpecified" fields. I could not find a way to cause the parameters to behave like in 4.0.4, so I had to modify our .NET code. Return values have the same problem - if an Integer is returned from Java, it is split into two fields "returnSpecified" which is true if null is returned and "@return" (yes, the "@" symbol escapes the "return" keyword) that contains the returned value. Last issue (the easiest to spot and fix) - the default argument names (if no @WebParam attribute is used) have change to follow the spec (now they are arg0, arg1, etc).
More JAXB issuesWhen bean classes that are used by the webservices are translated into XML, few incompatibilities arise:
Sometimes a webservice returns a class that has subclasses, as in the following example:
@Stateless
@WebService
public class TestClass2 {
@WebMethod
@SOAPBinding(parameterStyle=ParameterStyle.WRAPPED, use=Use.ENCODED)
public MyClass getMyClass() {
return new MySubClass();
}
}
@XmlType
(name="MyClass")
public class MyClass {
// field+method definitions here
}
@XmlType
(name="MySubClass")
public class MySubClass extends MyClass {
}
In JBoss 4.0.4 there was no problem. The .NET client would correctly receive the MySubClass as a return value. JBoss4.2.1+JBossws2.0.1 send MyClass to the .NET client. The @XmlSeeAlso annotation should hit the web services implementation that a subclass could be involved in the method call. However, simply using the annotation was not enough (.NET would complain about the SOAP message format). In addition to the @XmlSeeAlso(MySubClass.class) annotation on the MyClass class, I also had to add a namespace attribute to the @XmlType annotation.
Duplicate methodsOne of the most bizzare bugs that I've encountered was a case when I had two different @WebService-s in the same package, and both had the same method signature, except the return type:
package demo;
@Stateless
@WebService
public class TestClass1 {
@WebMethod
public long getValue() {
return 5;
}
}
package demo;
@Stateless
@WebService
public class TestClass2 {
@WebMethod
public int getValue() {
return 5;
}
JBoss confuses between the two and both methods will have the same return type in WSDL (e.g, both will return int). I couldn't find a solution, so I just had to rename one of them.
Upgrading to a newer HibernateRecently I discovered what I think is an instance of the EJB-263 bug. Hibernate JPA queries that should return a single result (I used "JOIN FETCH" to fetch some lazy collections) were returning multiple results - in fact if my single element has 100 elemenets in the lazy collection, I would get 100 elements from the query - all of them are the same object instance. To resolve it I had to upgrade to a newer hibernate (I used Hibernate 3.2.5, Hibernate Annotations 3.3.0 and Hibernate EntityManager 3.3.1). Note - during upgrade, you should copy the helper libraries (lib folder) too.
We just released FEST 0.5!
New features:
JList, JTable and JTree. Many thanks to Fabien Barbero for his contribution.
GenericTypeMatcher. The following example shows how to lookup for a JButton that has the text 'OK':
GenericTypeMatcher<JButton> textMatcher = new GenericTypeMatcher<JButton>() {
protected boolean isMatching(JButton button) {
return "OK".equals(button.getText());
}
};
dialog.button(textMatcher).click();
Platform, which contains platform-specific utility methods.
ContainerFixture now recognizes JFileChooserFixture and JListFixture. Many thanks to Fabien Barbero.
You can download FEST here (file fest-swing-0.5.zip.) FEST requires Java SE 5.0 or later.
Here are some useful links:
Feedback is always appreciated
Play. Estimate. Plan...assim diz o título desta ferramenta da Mountain Goat Software (Empresa conhecida pelo pessoal de Scrum). É uma aplicação na web que tem por finalidade simular um Planning Poker para equipes que estão fisicamente distribuídas. Isso por que uma das premissas dos métodos ágeis é a forte comunicação e para equipes que estão cidades/estados/países diferentes isso vai ficando cada vez mais escasso.
Como funsiona a ferramenta:
Uma pessoa é o moderador. Após ela efetuar login ela convida outros participantes para participar do game. Então a pessoa entra com uma estória para ser estimada. O time claro, precisará está numa mesma conferência, onde eles discutirão sobre o a estória. Depois cada participante escolhe um cartão sua estimativa para implementar aquela estória e aí então o moderador escolhe a estimativa para aquela estória.
No canto direito possui um botão de timer de dois minutos que é um tempo razoável para escolher as estimativas. Após isso a decisão pode ser exportada para formatos conhecidos como CSV e PDF (Essa funcionalidade eu não usei)
Acho que esta ferramenta tem muita utilidade em “equipes ágeis” que utilizam o planning poker e não estão localizados numa mesma sala.
Link da ferramenta aqui.
_uacct = “UA-2402321–1”;
urchinTracker();
Currently I'm in the middle of automating the creation of new projects in CVS and CruiseControl. I've found the way to automate the projects in CVS repository using the NetBeans javacvs library. One thing though if we are testing the CVS server installed in our local machine we have to use the LocalConnection class instead of the PServerConnection class.
As for CruiseControl I think if there is no API or web service call then I can just add the configuration into the config.xml and automatically CruiseControl will pick it up.
While we are at it let me rephrase it yet another way - “With GridGain we've taken Saint Exupery's principle quite literally”.
Have fun and enjoy grid computing!
Download GridGain at [www.gridgain.com].
To be able to collaborate well with Turmalix, hosted on the free, open collaboration platform JavaForge, the use of an Integrated Development Environment (IDE), on the desktop site, is more than nice to have. To make it fun working with JavaForge/Codebeamer, you have a choice of free IDE's to be downloaded from the web. The most famous ones are Eclipse and Netbeans.
There are philosophies on which IDE to prefer. I am grateful for all of them. Thanks to our new free open source culture, we seem to be living in paradise. Now we all can afford great software and be part of this adventurous open source circus. It is more like living as an artist than being an engineer. The collaboration in the web is the source for our inspirations and our creativity.
Eclipse is more than a myth: according to wikipedia the term is most often used to describe either a solar eclipse, when the Moon's shadow crosses the Earth's surface, or a lunar eclipse.
Wikipedia also has a perfect introduction to the Eclipse IDE. For developers to collaborate with Turmalix on our collaboration platform, we want to download the free open source software piece at the community site www.eclipse.org.
To explain how to install and set up eclipse would kill this weblog. Voila, it is done for you already: see "The Official Eclipse FAQs".
To be able to connect the IDE to the Turmalix subversion archive on JavaForge, we use the Eclipse plugin called Subclipse. This plugin gives us a simple and well integrated connection between our Windows or Linux desktop / laptop and our collaboration area. For details see 10 Steps - Accessing the Turmalix subversion archive with a client.
InputStream.read would never return less than the full length of the data, right?InputStream is = openStream();
byte[] data = new byte[dataLength];
is.read(data);
Copying a stream of unknown length
If you don't know the length of the stream you are reading, you will need an efficient and dynamic data structure to copy it into. Here's a perfect example:
Unfortunately, the most efficient way to do this in Java is a synchronized, dynamic list structure, byte wrappers, and lots of typecasting. Exception HandlingVector byteVec = new Vector();
byte bRead;
while ( (bRead = inputStream.read()) != -1) {
byteVec.addElement(new Byte(bRead));
}
byte[] data = new byte[byteVec.size()];
for (int i = 0; i < byteVec.size(); i++) {
data[i] = ((Byte)byteVec.elementAt(i)).byteValue();
}
If you ever have trouble with null pointer exceptions, just sprinkle these liberally throughout your code (preferrably lots of times in the same method, where the same variable is likely to be null):
try {
b.doSomething();
} catch (NullPointerException e) {
// ugh, it broke again, just ignore the thing
}
Callers never really want to see that the callee failed.
SummaryYes, these are actual examples from real code. I will not mention the developer by name. You will have to work quite hard to reach these levels... of... well... of something!
A quick follow-up on yesterday's post. After running through my unit tests, it appears that I forgot a basic element of Java usage: order of execution for constructors.
By setting a property to a new object directly in the field definition:
public class MyProperties extends PropertyGroup {
public final StringProperty myString = new StringProperty("default string");
public StringProperty myString2;
public final IntProperty myInt = new IntProperty(10);
public final FooBazProperty myFooBaz = new FooBazProperty("file.txt");
public MyProperties(Properties p) {
super(p);
}
}
that code for constructing the object is executed after the constructor completes. Therefore, if you allow for the class to construct new instances dynamically if the field is null, or if methods need to be called on the fields, it needs to run after all the fields have been initialized. This means that the setup code cannot be in the constructor.
Which makes yet another argument for supplying factory methods. Instead of forcing the user of the class to create a new object then run a setup method, just have the class provide a factory method.
This document discusses the current design of the Crank Validation framework. Specifically it covers the base framework not the specific JSF and Spring MVC bindings nor for that matter does it cover the Ajax/JavaScript support.
The document starts off talking about the Spring MVC and JSF neutral parts of the framework. Later it does discuss the Spring MVC and JSF bindings just enough to understand how the base framework is used.
This document does not cover the Ajax support for calling validation rules, the low level JSF integration, the low level Spring MVC integration, or the JavaScript based rule generation. Perhaps, one day those documents will exist.
Before reading the Crank Validation design doc, it may make sense to see some example code at: [code.