Wednesday Apr 24, 2013

Re-read [capaths]


[capaths] does not have the same meaning in JDK and the rest of the world (See references at the bottom).

In JDK, each line describes a relation and one needs to consult multiple relations to create a path. In the rest of the world, each line itself is a path.

So, suppose shared keys are between A and B, B and C, and, C and D. For a client in A, in order to visit a service in D, it needs A -> B -> C -> D.

In JDK, the capaths is written as

A = {
   B = .     # I can go B directly
   C = B     # To go C, I need to go B first
   D = C     # To go D, I need to go C first

In the rest of the world, it's

A = {
   B = .    # I can go B directly
   C = B    # To go C, I need to go B. Done
   D = B C  # To go D, I need to go B and then C. Done

and the last line is often written into multiple lines

D = B
D = C

although this becomes not so clear.


When a sub-tag has multiple values (either on a single line or multiple lines), it is interpreted differently.

A = {
   B = C D
  • For the rest of the world, it's a series of realms that the client needs to walk thru to the server. The client in A needs to go to C and then D to reach B
  • For Java, it's a list of alternatives that can lead to the server. In order for a client A to go to B, it must reach C or D first.

and the Java way is wrong.


There will be a behavior change anyway, but we must preserve as much as we can. That is to say, if there are no sub-tags with multiple values, we do the same as before. If there are, we should treat it correctly like the rest of the world.

Here is a way to unify the two different designs. For

cRealm = {
   sRealm = A ... B

"A ... B" should be regarded as a (possibly partial) path from cRealm to sRealm.

The key point here is the "possibly partial" modifier. By partial, it means the path could be only the tail, i.e. you need to find zero or more realms "C ... D" to build the full path "C ... D A ... B", where C directly shares keys with cRealm.

Now, the rest of the world always gives the full path, and JDK gives the shortest-available partial path. Unified.

How to build the full path then? Given the previous example

A = {
   B = .     # I can go B directly
   C = B     # To go C, I need to go B first
   D = C     # To go D, I need to go C first

From D = C, we get partial path for A to D as C -> D. Here A cannot directly go to C, so we start building. We have C = B, we have a partial path for A to C as B -> C. Merging the partial paths give a longer path from A to D being B -> C -> D. B = . shows B is a direct link, and we have the full path.

There are still some rules:

  1. . can only appear in a single-valued sub-tag
  2. No loops
  3. No dups in multiple values of the same subtag
  4. Neither cRealm nor sRealm can appear in path

If any rule is broken, the output is undefined. The current implementation is that the value is ignored.


From the discussion above, we can say that previous JDK releases still work if there is no multiple-value sub-tags. This means you can always rewrite "A = B C" to two lines "A = C" and "C = B". Both the old JDK and future JDK will recognize it. Unfortunately, the rest of the world does not like this format, say, MIT's krb5.

And, the Hierarchy Case

The hierarchy algorithm is also wrong: When two realms have completely no common components, Java now regards it as a direct link. However, the correct path should go down to the last component of cRealm, and then go up from the last component of sRealm to the full sRealm.

For example, a path from A.COM to B.ORG will be A.COM -> COM -> ORG -> B.ORG.


Sunday Mar 02, 2008

OpenJDK is fully opened!

Mark finally announces the opening of OpenJDK code repository, which means new code changes (bug fixes, enhancements) can be contributed into the OpenJDK from now on. I don't know who will push the first changeset. I dare not do that. Let the real Java gurus go first, say, Duke himself.

Wednesday Jan 02, 2008

mICroSofT knows

There's guy got confused at Java's Kerberos support, the reason, AFAIK, is because he's using lower case letters in the MSAD realm name.

Certainly Java won't accept that, when the returned realm name in a KDC-REP message is (case-sensitive) different from the one sent in KDC-REQ, there's an error, and a KrbException is thrown.

I've tried to tweak the JDK codes to ignore realm name checking and do some case-changing experiments. Every one passes smoothly, realm names, host names, service names, whatever. Everything works. Microsoft just doesn't care about cases. We know it has a long history of acting like this. BASIC language doesn't care about it, neither do DOS filenames. Last time we added pre-authentication into JDK's Kerberos so that you can enter your user name as either Bill or bill or bIll. And now, do we need to meet this ignorance again?

I'm not a lawyer, I have no idea if the embrace, extend, and extinguish means is legal or illegal in what extents. When someone extends an existing standard (in the MS way), which way shall the standard goes? Just ignore it? or re-embrace it? There's surely the risk of making the standard into a total mess some time.

Wednesday Dec 19, 2007

Struggling with Mercurial

The OpenJDK repository is still not writable now, or at least, we're told not to write to it. There're still some rules to be worked out on what the comments should be, how code reviews get done, etc, etc.

But at the same time, I still have to get my work done, fixing bugs and implementing RFEs. The teamware workspaces are gone, and I've fcloned the whole forest on my own computer. What shall I do if I cannot name the changesets and push them back? So I'm trying the Mercurial Queue extension now.

The tool is great by letting you doing groups of code changes one after one, in a special kind of changeset called patch. They're real changesets, except that it's very easy to apply or de-apply them as a series. Therefore, it's an ideal tool for me now to work on bugs/RFEs one after one, and I know I can change the comment names later.

I've found several problems (and solutions) so far:

  1. You have to to work on them one after one, which means you cannot work on several bugs simultaneously. Without the extension, in the simpler case, if several bugs need changes in different files, you can just do them both. When any one is done, run "hg commit filenames" on its affected files and the changes go into its own changesets, and then the other, the other. With the extension, I don't know if I can control "qnew" and "qrefresh" to act on a sub area of the whole repository. Seems not, so I have to create multiple patches, and "qgoto" the one each time I want to work on another fix (and remember to qrefresh before switching to another one), even though they are touching completely different files.
  2. There's an order of which patch comes after which. This order is determined when each "qnew" is called, and finally they should be pushed back in this order. What if I need to change the order? What if I just have to drop one? My current solution is to manually edit the "series" file after calling "hg qpop -a", and them qpush in the new order (Thanks to the clean and whitebox designation of MQ. You're so kind!). Sometimes, if 2 patches make changes to the files, I use the "flippatch" tool to update the patches themselves. Of course, manual check is always a must after the flip, to make sure the history is not corrupted.
  3. I don't know if there's a standard way to change the patches into formal changesets when I'm sure the upstream repository already accepts my push backs. I can manually edit the "series" file again and remove the patches. This is not a serious problem. Update(2008-01-04): Just write a script to automatically change the topmost patch into a normal commit. I just qdelete the patch from series, patch it explicitly (by running the patch command), and then commit it. I've made sure to take care of the added and removed files.
I haven't read the Advanced Usages of MQ yet, maybe my questions can get answered there.

Wednesday Dec 12, 2007

A JNI wrapper for NetBeans

I'm looking for a way to ease JNI developing through NetBeans. Whenever a native method is declared in a Java file, this plugin should aid the developer to implement the method in a native language, promptly, and intuitively.

Actually, just try it manually:

  1. Create a Java app, declare a native method inside
  2. Compile it. Run javah in a terminal window.
  3. Create a C/C++ dynamic library project
  4. Add include directories for JNI (and system if not there yet)
  5. Link the generated header file into the C/C++ project
  6. Implement the method in C
  7. Build it, success!
  8. Link the dylib back into the build/classes directory of the Java project
  9. Add the System.loadLibrary static call
  10. Compile and run, success!

Similar project already exists. Maybe can co-op.

Wednesday Dec 05, 2007

Netbeans 6 final on Mac OS X

There used to be a very annoying problem running Netbeans on Mac OS X (or, at least on my system): When I scroll a list view, say, the project window, or the plug-ins directory, sometimes the old texts are not cleaned when new texts are printed, and they overlap. Scroll and Scroll, and they overlap and overlap until there are only black messes inside the window. You have to click inside to force a clean redraw to see the content.

I thought this was a Swing problem. Since I've never seen the same thing on other systems, I thought it's a Mac Swing problem, a bug from the Mac port of Swing (by Apple guys) to adapt their native l&f. However, after installing the final bits of Netbeans 6.0, it seems this bug does not appear anymore. Maybe I was wrong about it? that it's a Netbeans widget instead of a Swing one?

Anyway, I pray when I launch Netbeans the next time, it looks still clean.

Tuesday Dec 04, 2007

My 0th contribution to OpenJDK, the public source repository

I guess I have successfully created some inconsistency into the dryrun OpenJDK Mercurial code repositories. This may lead to a new discipline for all OpenJDK developers:
Thou shalt not "hg push -f".
In fact, you may not be able to do it at all.

New OpenJDK platform?

If someone wants to support a platform. What should be the process?

  1. He creates his own repository, start coding, report progress on some OpenJDK mail list.
  2. He may start distributing it now, but...
  3. If some other guys also think this is important (serious), they may together request a new group inside OpenJDK be established
  4. If the request is approved, the guy gets the chance to create a branch on the main OpenJDK source repo server. Otherwise, go back to 2.
  5. It's a branch and while its maintainer can merge changesets from other repo. Other repo (mainly, the MASTER repo) won't merge from it, until...
  6. It's important enough to be included as an official build (currently there are 8). Then...
  7. If it includes quite a lot of different codes from the main repo, there'll be a platform sub-directory for it created inside jdk/src/[platform]/. Otherwise, it's merged into an existing sub-directory (currently, there's solaris (soon to be renamed to posix?), linux, and windows). For example, some minor updates to IBM AIX flavor of Unix will be coded into the main posix source with a few #IFDEF lines.
OK, this is what I'm guessing.

Friday Aug 31, 2007

Netbeans 6

Netbeans 6 is almost out.


  1. Much Improved editor (esp. close window by mid-button)
  2. Fast initial Java platform evaluation time
  3. Mecurial and Scala


  1. debug-single and run-single need compile, instead of compile-single
  2. no support for teamware anymore

Monday Jun 25, 2007

Java FX Script bind

Just take a first look at the coding of Java FX Script. I'm quite curious on the keyword bind now.

First, I read this line:

image: Image { url: bind pix }

OK, this is good. So it means the image field has a url property that is bound to another variable pix. When pix changes, the url of the image changes also and it redraws. So, it's an automatic set/get/trigger/onChanged... two-way messaging mechanism. I like that.

However, looking back at what pix is, I see this line:

var pix = bind "http://somewhere/something.gif"

That's a little strange, pix is bound to a literal string? And then I see:

var x = bind 0

Totally ridiculous. This is like in C++, we should not write "int& x = 0" or "int\* x = &0". 

While x cannot be bound to a constant, something else can still be bound to x. I somehow understand that this bind keyword, when used after the assignment sign for a declared variable, seems to show that this variable itself is a "binding" (bind-able) variable, which means when it's assigned to something else, it's more sort of a symlink/alias than an assignment. If this is right, I'd rather like the grammar to be changed a little to use bind as a modifier:

bind x = 0 

Back to the first line, what does "url: bind pix" mean? This "bind" is not a modifier on pix, it's already declared as bind somewhere else. Is it on url? Not likely, because url is defined as a property of the Image class, being "binding" or not should have already been decided at the definition of Image. So this bind keyword here, is used to declare a binding relation between 2 declared variables. This looks like in C++, we change a normal variable into a reference.

int x = 0;    // x is a normal variable
int y = 1; // y is another
&x = y; // x is redeclared to be a reference of y

Note: I admit I'm not familiar with data binding, or RAD tools, or any event driven programming. I even don't know if this "bind" is the root form of that "bound".

Monday Jun 11, 2007


Yesterday I download the Fedora 7 iso to install it in my VMWare. I haven't touched Fedora for a long time since I started using Ubuntu. The single reason (yes, the only one) is that I prefer a CD-size iso much much more than a DVD-size one, even if I have to install something from the Net after the installation.

The reason I install Fedora is because I want to try out the IcedTea project from RedHat (or, some RedHat guys), which provides a way to compile the OpenJDK sources with 100% free software, that is to say, no Sun JDK 6 for bootstrapping, no binary plugs to download for components still missing from the OpenJDK sources. This is so cool and great and it's the latest (probably the most promising) proof for me that doing JDK using the free and open source approach is the best thing we can do for the Java community.

After a simple hg clone and ./configure and make, it automatically downloads the OpenJDK source codes (sans the binary plugs), patches it, and starts the making process. When I look again into the Fedora console (thru VMWare thru rdesktop thru VNC), it's finished, with a line of warm words:

IcedTea is served: openjsk/control/build/linux-i586

The directory looks exactly like the JDK control build tree I'm familiar with. There's a gnu directory inside classes which includes an awt package and a security packge. That's just the components we cannot ship in the OpenJDK, right? Are they really provided to plug the holes?

First, I try the NotePad GUI demo, comes the error message "undefined symbol: setSunFontIDs". Not a nice output. Then I tried a tiny program on encryption using the Cipher class, this time the error message says the DES algorithm is missing. So the function is not actually plugged, only the build process is plugged.

Anyway, this is my first try on OpenJDK. At Sun's JavaOne OpenJDK booth I had tried to play with it but unfortunately the machine there has only the normal Solaris installed but not the Solaris Express Developer Edition, hence no compiler. The second time I almost decided to download the huge binary plugs but read Kelly's mail saying he's about to slim-ify the file, and I stopped again. I believe even with the sources and binaries from the OpenJDK site, the final built still cannot do GUI and Cipher. I try several commands of keytool and it works happily, so it's still a working version. That's enough now.

Friday Apr 06, 2007

I get the timestamp!

It costs me several days to finally get the timestamp signing ready. The most complicated things, of course, are still understanding RFC 3161, writing the server with PKCS #7, and constructing the ASN.1 DER bytes. Besides these, I also learnt (yesterday evening) that unlike the code signer, which shows a dialog if it's not trusted (shown above as item #2), the timestamp authority must be trusted by the Java Plugin ('s root CA). Otherwise, the timestamp is silently ignored.

Tuesday Mar 06, 2007

Roumen's Cars

This demo on Netbeans support on the Swing Application Framework is absolutely, hilariously, tremendously cooooooooooooooooool!

Roumen's Cars

Monday Mar 05, 2007

Reading Zip files with non-ASCII file names

In a zip file, each entry occupies one slot, which includes a description and the compressed data. Of course, one field of the description is the file name. There's this unfortunate thing that in the original ZIP specification the encoding of the filename is not specified. Most applications choose the default encoding (or, native encoding of the underlying operating systems). For Java, since i18n was considered at the very beginning, and the language has a strong wish to be cross-platform and cross-locale, it chooses the UTF-8 encoding, since that's the only (?) charset that's guaranteed to be supported on every platform and supports every character in the world.

So here comes the co-op problem. If you compress files with Chinese names using WinRAR, it will not be opened by the jar command. Another popular sofware, GMail, also uses UTF-8 when you download several attachments at once, this time, the file you get cannot be opened by WinRAR (use jar, only in JDK).

I do not care about this until recently I try to start playing with Java ME. The first program I want to write is showing what's on now for various TV stations. On the website of CCTV (China Central Television) there's a schedule file for almost all TV channels I can reach. Each channel has one file in the zip bundle, and the file name is the channel's name, in Chinese, in the GB2312 encoding.

If I were writing a Java SE program, I won't hesitate a moment to go inside JDK, change the lines where UTF-8 is forced and thus OK. This is my version of private JDK, I can do anything on it. But for Java ME, I don't know a way to substitute the JRE in my phone with a customized one. (Maybe I can ask the ME guys underfloor)

This is what I did:

  1. Read the zip spec, only the first 4 pages, about the overall layout and the structure of the entry header
  2. Write a FilterInputStream, override the read method to translate the file name from Chinese encoding (gb2312) to UTF-8 on the fly, of course, also update the filename length. This filter let all other fields (as well as compressed data) go thru transparently. After all zip entries, there are still quite a lot of blocks (started with [archive decryption header] if you read the spec). I really don't understand what they are. Shouldn't any data after all zip entries be useless, at least in streaming mode? So, I regard them as a big EOF, and let read() returns -1 when this part is met.
  3. Insert this filter between the InputStream of zip file and ZipInputStream, everything is OK now.
I'm not in the mode of writing an output filter at the moment. If I do want to evolve this into a common tool, maybe I need to have a look at the rest 95% of that spec.

Thursday Mar 01, 2007

New Java Deployment Style

There're quite a lot of new proposals for the deployment style of next-version JRE, some focused on the end-user experience, some on updating schedule, some on component dividing, some on enterprise deployment. As a JRE user, I agree on all aspects, and as an developer, I hope they are carried out in a consistent way around a solid architecture and a clean design, so that a few core concepts can offer multiple purposes in a nice style.

For me, I especially would like these points becoming true:

  1. Any code change should be labeled enhancement, normal bug fix, or security bug fix. The last one should be released as hot patch (detailed descriptions for licensees).
  2. JRE should be divided into components in a reasonable granularity (small, but no smaller. Developers should be satisfied by re-organizing them in most cases, instead of hacking inside and create special releases, aka, forking). The components have dependencies among them, there are versions. Sometimes two components may be parallel (alternative), which means one and only one can be activated.
  3. Non-core components should be able to plugged into multiple versions of JRE, like JSSE, JGSS,...



This blog has a comments managing system that requires me to approve each comment manually. Please do not re-post and I will reply it (if I have an answer) when I get pinged.


Top Tags
« February 2017