It's Time to 'Re-Align' the JCP?
jgeelan writes "The original glorious premise behind a J2EE container was to abstract multithreading issues, server memory management, wire protocols, and so on, from Java programmers and allow them to focus on implementing solutions, not server infrastructure. Yet in the current issue of Java Developer's Journal, the director of technology at Personified Technologies, Jason Weiss, has lit a flame under J2EE, the jewel of the Java specification crown. The spec, writes Weiss, is too complex. As a community Java developers must pay attention to the beleaguered JCP process and realign it with creating solutions, like those routinely released by the Apache Software Foundation. Weiss argues that by taking steps now, Java developers would be investing in the future both of Java and the community that has grown up around Java. 'The entire JCP process must thematically reflect our desire to build solutions that simplify complex technologies for programmers,' Weiss continues. 'In fact, the JCP process should continue to use the JSR acronym, but with new meaning: "Java Solution Request," he adds.
'Somewhere during this journey the JCP has shifted from its solution-oriented roots to merely implementing specifications. This trend must be reversed ... for the sake of our community.'"
These guyz arent the normal M$ biggots. Looks like Personified Technologies is an ISV who actually bets their business on Java. Just very interesting to see some self-criticality and not ranting from the M$ sloths.
js
It doesn't disrespect java.. it just puts java in it's place. Java is a terrific server side , and web-based, and distributed OO language. (hense j2ee being the topic) As far as speed client GUIs go, java swing sucks goat nuts. Dunno why.. it just does. if I were to right a client side app (in windows), I'd go for .NET / C#. It's as easy as swing... and much much faster and cleaner.
--noodles
A fourth capability, in the first released version of java, but not used to its fullest capacity until Java2, was the use of "interface" over abstract base classes as a means of building frameworks in the newer library components such as JDBC, Collections, and XML. C++ always had this, but "interface" is a much simpler syntax and means of expression verbally over "abstract base classes with only pure virtual functions" (the C++ version of a Java interface). Also, newer C++ libraries and designs tend to rely on templates and traits to enforce an interface (ala generic programming) rather than class design, because its easier to just write a class than to design a hierarchy -- java's "interface" took the hierarchy out of places it didn't need to be).
Now, one of those ended up an utter failure (AWT), and its replacement (Swing) though amazingly more successful as far as design and power goes, is as noted dog-slow (though its something that does get faster as machines get faster; moore's law does help Swing considerably). I personally love swing just because (when used properly) the WORA DOES work (layout management is the #1 problem for almost every bad interface out there, and that's not unique to swing; i recall a lot of bad motif layouts too from windows programmers not used to Xt's approach); also, the power in using renderers for complex components and dividing up responsibility of showing the look vs managing the data, is something i miss in any other gui library out there.
The second, the standard networking library tied to the I/O library, remains its brilliant point and the basis for Java's most successful libraries and projects, including all its server-side work. Bjarne is most impressed that the standard socket + stream library that works on ALL platforms (its the one that's most reliable in that respect of WORA) that he's planning to propose a standard socket interface to C++, though I think its now too little too late. I'm not saying that java.net and java.io aren't flawed. The use of abstract base classes for Socket and URLConnection, which likely dates to before the interface keyword was introduced is a "bad thing"; java.util.Dictionary was like this as well, but at least that's been deprecated out. Similarly, java.nio addresses most of java.io's problems, but at the considerable cost of code simplicity; if you need java.nio, it'll take a lot of time and work to use it correctly, and few books and articles are really making it clear when you actually need it. In the early stages of new technology, the "how do i use it" well-buries the "when do i need it" question.
The language itself has remained simple, with only 2 partially-incompatible changes over the years (inner classes including anonymous, and assert), and this may be its one saving grace against C# (which has a more complex syntax, but currently a much simpler library based on a cleaner syntax to most of MFC -- that will change in the future as M$ will always code-bloat their products).
The "interface" syntax is to me still Java's most powerful feature; again not in that it provides any more capabilities over C++'s abstraction (as i worded it above), but by being so simple, did more to improve inexperienced developer's OO code than any other OO syntax out there (IMHO). I'm not suprised at all that C# also chose to keep the interface keyword.
"But remember, most lynch mobs aren't this nice." (H.Simpson)
-- Joe
Why can't I 'Object i = 5;'? There should be a 'void*' type.
You don't want a "void*" type; you just want int and the other primitives to be fully privileged objects (subtly different). This is probably the most common criticism of Java, and it's reasonable. There are also reasonable arguments for having primitives apart from objects, however. They didn't do this without some thought. Still, I lean toward your opinion on this one.
Why can't I 'Method m = Object.toString;'?
Reasonable -- it's a little shorter than Method m = Object.class.getMethod("toString", new Class[0]). But it's not a big issue -- in most cases where you'd use that, an interface paired with an anonymous inner class is more appropriate (and typesafe).
Why can't I [stuff] and get the right method called!?
Because that's a pretty wacky idea. Think for a moment about the implications of what you're proposing here -- x ? y : z is an expression...what is its type?
You could make this work, but would it be worth the hideous mess it would make of the spec to save you from having to type the words if and else?
Why can't I 'import java.util.*String*;' or 'import java.*.*;' ?
Because it poses tremendous potential namespace conflict problems with little clear benefit.
Why do we have 'new' instead of alloc and init?
Separating instantiation from initialization is reasonable; static factory methods do this just fine, but require foreknowledge of the problem. Such a facility, however, would still need to provide the guarantee that you can't actually obtain a reference to an object until it's fully initialized, which is where a naive implementation looking like like MyClass.class.alloc().init() would fail.
Why aren't static methods inherited?
Because that's an absolutely hideous idea. Static methods aren't part of the signature matching that underlies the type system, and don't participate in polymorphism; they are semantically equivalent to methods on the class, not the object (which is how Smalltalk does it).
I'd add to your list the lack of generics (which they're working on) and some of the unpleasant aspects of the memory model on multiprocessor machines.
You don't. You use JBoss. Why would you build your own server from scratch when you can already customize and extend the JBoss core server as much as you need (be it for J2EE purposes or not).
Using the types of the arguements for the method lookup is not wacky. Haskell does it. I don't know the right words to use, but it is like polymorphism including the arguments, not just the target.
// empty thinger ctor ... }
... } ...
Java does use the types of the arguments. For example, the following will do what you want:
Object f(String s) {something(s);}
Object f(List l) {somethingelse(l);}
void main(String [] a) {
if(a.length == 1)
f(a[0]);
else
f(Arrays.asList(a));
}
The reason the code you posted doesn't work isn't that Java doesn't use the compile-time types of the arguments to resolve overloaded functions. Rather, it's that x ? y : z is an expression, and it needs to have a single type. What is that type in your example? Do you want expressions to have a set of possible types, like {String,List}? That's what I was saying would play hell with the spec. Or do you want the expression to have the type Object, and have overloaded function resolution use runtime types? If so, you lose a lot of compile-time type checking.
The reason Haskell lets you do this is that it's much more weakly typed than Java. Personally, I like the strong typing, and I think the inconvenience here is minimal.
I guess I just have problems with static methods. This goes back to implementing alloc().init(). You can't do it with static methods.
Actually, you can. What you're looking for is the static factory method pattern. Here's an example that returns a single shared "empty instance" of a class if an argument is null or empty:
public abstract class Thinger
{
public static create(String thingerValue)
{
if(thingerValue == null || thingerValue.length() == 0)
return EMPTY_THINGER;
return new Thinger(thingerValue);
}
private static final Thinger EMPTY_THINGER = new Thinger();
private Thinger()
{
private Thinger(String thingerValue)
{
}
You then say Thinger.createInstance("foo") to use it. The static method takes the place of your "alloc", and the constructor is the "init". You can also use this technique to return a subclass of Thinger; give the subclass a package-private constructor if you're worried about outsiders instantiating it.
I think this does everything you want. The only problem with this technique is that you have to know that you're going to do it ahead of time -- you can't retrofit a constructor as a static factory without breaking the API.
generics
Your proxy thing is nifty at a glance. Generics are supposed to be there soon -- quite possibly in 1.5 -- and promise to be good.
2) A well written CMP2 engine will give you a great deal of flexibility on how JDBC is used (read-ahead buffering, load groups, etc.)