This is a rant about Java Client, but really about Java Web Start,
XML config files, and Lazy Engineers.
If you find such things amusing, read on.
I do provide solutions to a couple of problems with Java Client in
the hopes that with the aid of Google, this will help someone down the
road.
Ok, so I got our Java Client app working finally. But I still hate
Java Client for several reasons.
REASON #1: Java Web Start Sucks
JWS is a classic example of sounds good in theory but sucks in
practice. The theory is that instead of having to deal with upgrading
a whole bunch of users to the latest version, you provide a
configuration file of what jars are needed, and JWS will download the
required jars if necessary to the users local system.
In practice, JWS violates Pierce's Rule for config files on several
levels. For those of you not familiar with Pierce's Rule for config
files (and why would you be, I just made them up), I will state them.
Pierce's Rule for config files: If writing a "Hello, World"
application requires me to write a 2,000 line config file, your
technology sucks. This means you Struts/Hibernate/Ant.
Pierce's XML addendum: If the config file is in XML, make that 100
lines, because XML is much less unforgiving then the average
programmers "read a bunch of properties from a file" format. I also
have yet to see a commented sample XML config file that does as good a
job of being self documenting as say, apache.conf. That of course
means that Struts/Hibernate/Ant suck by an extra factor of 20.
Pierce's GUI exemption: If you provide a GUI for editing the
config file so that I don't have to learn an entirely new programming
language to get started, it doesn't matter how big the file is because
I'll never look at it. (Every XML file I've ever seen is essentially
learning a new programming language, which is yet another reason Ant
sucks)
Pierce's GUI exemption qualifier: If the GUI tool doesn't support
everything the XML file does, then your config file format must suck.
Rewrite the format to make the GUI tool easier to write. The GUI tool
rules, not the XML. Otherwise, you can't claim the exemptions, Nyah
So Java Web Start requires this giant JNLP file to be written.
Helpfully, WebObjects generates this for you. However, JNLP is broken.
It's broken because the idiot at Sun who created JNLP decided that
JNLP would only allow one certificate to be used to sign jars per jnlp
file. He did this so, get this, "you wouldn't have to specify multiple
certificates in your .jnlp file".
Translation: "I'm a moron who doesn't understand security."
Since wojavaclient is signed by Apple, that means your remaining
jars have to be unsigned, or you have to do the following doh-see-doh:
Instead of using:
<jar href="jh.jar"/>
Use:
<extension name="Java Help" href="help.jnlp"/>
And then, you have to make yet another XML file that looks like the
following:
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+"
codebase="http://ws503" href="Help.jnlp">
<information>
<title>JavaHelp</title>
<vendor>Sun Microsystems, Inc.</vendor>
</information>
<resources>
<jar href="jh.jar"/>
</resources>
<component-desc/>
</jnlp>
See:
http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/faq.html#213
Why this is lamebrained: First off, this doesn't supply any extra
security. Sun claims: This restriction avoids requiring the user to
accept multiple certificates from the same source, and enables Java
Web Start to know if the user has accepted all certificates used for
an application.
This is just so amazingly asinine a statement that I barely know
where to begin. Since JNLP lets you load all the unsigned jars you
want, this arbitrary restriction isn't providing any security. Unless
like BouncyCastle, the jar requires itself to be signed, a cracker
could substitute an unsigned jar, and Java Web Start wouldn't check.
So there's already a giant security hole here, you should be able to
specify that not only should a given jar be downloaded, but that it
has to be signed. Additionally, the whole PKI system is built around
the idea of one cert vouching for another, so the JNLP file should be
able to say "Things signed by say, Sun" are ok, and if the user
approved your cert, you can extend that to Sun. In other works, it
violates another of Pierce's rules:
Pierce's Rule on Code Signing: Signed Code should be superior to
unsigned code, not inferior. If signed code is a second class citizen,
your security system is broken.
Plus this is Java Web Start, so one would think that perhaps if you
served the jar file from an https server, they would all be considered
to be signed by the servers cert. That would have been a much more
sensible solution.
Ok, so given the above, what do you think the chances are that
Apple's helpful JNLP generator does the above doh-see-doh?
Zero.
Which means its basically broken. If your code uses a signed jar,
it will generate bad JNLP files. My solution was a hack, I basically
just hardcoded the list of jars to download and edited the ones that
needed to be edited to load <extension href="foo.jnlp"/> instead. I
suppose, I could have rewritten the .jnlp generator to look at the
jars and do the doh-see-doh in that case, but screw it, Apple should
do that.
Even if you think I'm just whining about all this JNLP file, note
that you've traded problems with getting everyone to use the latest
version with problems with their Java Web Start Cache. You also have
to explain how to use the Java Web Start Cache on every platform, and
what that whole "save as a desktop application" thing means. Much
easier to send out an email "Download this!", because you don't have
to train your users how to download new software, they're used to
that. JWSC is a whole new thing for them to learn.
Reason #2: Lazy Engineers
So Apple has this /Library/Java/Extensions mechanism where you can
just drop jars in there and all Java apps will see them.
If only it were that easy. For security reasons, because the jars
in there load before anything else, instead of after everything else,
any jar you reference from Extensions that references another jar has
to find that jar in Extensions as well. So it ends up being viral,
once you put one jar in Extensions other jars get pulled in. I dare
you to find a jar that DOESN'T reference apache-commons-logging these
days...
Meanwhile, any jar pulled in from Extensions doesn't get listed in
your jnlp file. Which means that your Java client may have a
dependency on something, and you'll have to find it the hard way, at
runtime.
In our case, because no one had ever made a jar Framework to pull in
all the extraneous jars, we ended up with 3 separate packages
.client: The client classes.
.common: Most of the code.
.server: Code that had to live on the server, because it used
some jar not on the client.
Which means we had 3 versions of User.java. Which pretty much
guaranteed you edited the wrong one... Because everytime the client
tried to do something that wouldn't work without the standard set of
Java jars, the engineer involved would just move the code to the
server and add yet another remote call in Session.java.
So you can fix this by building a Jar framework project and
pulling everything out of Java Extensions. Except the JNLP file is
generated by the server code, not the client code. So the JNLP file
ends up downloading EVERYTHING the server uses, because it has no way
of knowing what's actually necessary for the client, since the server
code is running...the server code.
Plus the list Apple provides isn't totally complete anyways, in my
case, it turns out my Java client needed EOAccess for some reason. So
I had to add that by hand.
Moral of the story: Don't use Java/Extensions. If you are using Java/
Extensions, be prepared for some hurting when you move away.
Thank you for listening.
Pierce
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (Webobjects-dev@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [EMAIL PROTECTED]