As Oracle does not provide signed checksums for their Java VMs, I took the time to compute the checksums of the Java VMs I've downloaded over time. (For now these are mostly 64bit Linux Full SDK gz Files)
If your sha256 checksum differs, then either you got a tampered copy or I did.
If you find this list useful, feel free to drop me a line.
The first column contains the name of the Package I've checked. You can read the SHA256 checksum in the second column.
Clicking on the SHA256 sum will give you a file containing that very checksum along with a signature you can verify (against server tampering) using my (old) public key (ID=7292C206).
Meanwhile Oracle provides SHA256 checksums on their secured Download pages for recent VMs (eg. 8u202) on their own. Even though no significant agency has access to Oracle servers, I am still providing copys for comparison :-)
Given the following regex a|ab
, which part of xaby
would you expect Java to match? Hint: it's not ab
as it would be for the regex ab|a
.
There is a debate going on whether a local variable, which is being assigned to only once, should be declared final or not. I don't want to dig into this debate, but there undoubtedly is a case where it is perfectly useful.
class Outer { void somefunction() { final var = ... new Inner() { ... use var ... } } }
However, that is the actual life scope of var? Does it live as long
as the outer object lives? I did not find anything in the spec about it.
But peeping into the code via javap -private -c "Outer$1"
revealed
that the compiler will pass var to the anonymous class via an invisible
constructor and store var in an instance variable.
I was relieved to see that Outer will not be cluttered with invisible instance variables.
Groovy/Grails is pretty cool, but in my opinion the design makes too heavy use of DSL.
One is supposed to use "interface by convention" (DSL #1) to implement requests to web application. Here is a controller replying to http://host/webapp/my/summary
:
class MyController { ... def summary = { ... see below ... } }
This controller is supposed to produce an xml reply, so I use DSL #2:
render( contentType: "text/xml" ) { entries { for( e in data ) { entry { text { e.content } } } } }
In this case everything works as expected:
<entries><entry><text>some text</text></entry></entries>
But in my application the element "entries" should be named "summary" which does not work. Groovy would interpret the element name as the method of the controller. The call then leads to endless recursion.
So you cannot create element names equalling to controller URIs?
Even worse, "entry" should be named "message" and I still have to figure out why this leads to omitting the element tags completely.
Moral: DSL should be used with the same care as operator overloading
I recently had a bunch of threads each taking data from the previous one and passing data to the next. The code was roughly like this:
class Worker implements Runnable { public void run() { while( !eof() ) { put_to_next( alter( get_from_prev() ) ); } finish(); } } ... for( int i=0; i<n; i++ ) worker[i].init(); for( int i=0; i<n; i++ ) t[i] = new Thread( worker[i] ); for( int i=0; i<n; i++ ) t[i].start(); // Wait for the last worker t[n-1].join();
Everthing worked fine, but once in a while one of the
workers behaved as if finish()
had already been called when entering get_from_prev()
. There, an exception was being thrown indicating that finish()
had already been called. I was absolutely sure that the worker was properly initalized (init()
had definitely been called!)
I was beginning to lose my faith in the memory management of the Java VM
until I remembered that the workers were being reused. So the problem was that
even though I waited for the last worker, the workers before were not neccessarily
finished. The finish()
of the previous run was being called after
the init()
of the next one.
The solution was simple. Waiting for the last runner is not enough, one also has to wait for the first.
for( int i=0; i<n; i++ ) t[i].join();
In a constructor the first call must be the call to the constructor of the superclass. Before that call is completed you may not assign values to instance variables. Hence the following Child is not allowed:
class Child extends Parent { SomeOb ob; public Child() { super( ob = new SomeOb() ); } }
You cannot assign to local variables either as the declararion already counts as statement.
public Child extends Parent { SomeOb ob; public Child() { SomeOb tmp; super( tmp = new SomeOb() ); ob = tmp; }
If the Parent provides access to the Object you can revert to:
public Child extends Parent { SomeOb ob; public Child() { super( new SomeOb() ); ob = getSomeOb(); }But what if there is no such call as in BufferedReader for the Reader? Don't despair, there is an easy solution! All you have is to create another constructor accepting the object to handle:
class Child extends Parent { SomeOb ob; public Child() { this( new SomeOb() ); } private Child( SomeOb ob ) { super( ob ); this.ob = ob; } }
This way, by creating a new constructor you have also created a new scope in which your newly created object has a name. You can safely use this name for assigments after returning vom the super constructor.
You have to bring the garbage out, if you want to have it collected
After starting with Java I really liked the fact that I didn't have to free unused objects.
Well, there is still the need to null out references to objects you no longer need. For example, if you have a FileLoader class storing the contents of the file in an instance variable, you have to set the reference to that loader to null if you no longer need that content - or you have to write a close method in FileLoader setting the content to null.
This issue is widely known, but espacially in Java there is more! I wrote a program reading thousands of files with a total size of more then 500MB. I thought I made everything right (see above), but the program still ran out of heap space. I was baffled, the profiler told me that all content was on heap but I was sure having cleaned the content variable in the relevant loop.
What was the culprit? The program ran fine for months, only after replacing my regular expression library against another one [1] the memory consumption increased. Was the library that inefficient? Was there a memory leak? I took care that the regex patterns were being nulled, but that didn't help either.
Finally (with Java 6 and jhat) I found the source of the problem: Java tries some clever things with char sequences. A String does not "own" the char[] holding the actual data. Instead it stores an offset and a length into a possibly shared content, an instance of char[]. Creating a substring does not need to do a copy - you only create a new String with the appropiate offset and length into the same content.
Altough the content "String" was being reclaimed, the underlying char[] arrays were not. My program extracted some match result "groups" from the files. The old library constructed the groups somehow and hence created new Strings, whereas the new library returned true substrings. Sounds like a good idea, but in my case it bites.
Luckily Java provides a solution. The constructor String(String) creates a copy of the underlying char array [2]. All I had to do was to replace data = matcher.group(n) with data = new String(matcher.group(n)).
Isn't it stupid that a Java VM cannot change it's current directory? Well, there are some security considerations to be taken.
Until SUN provides a clean thread safe interface to change the current directory you are welcome to use this small jar File.
It provides a JNI based access to query and change the current working directory. Just set the the directory where to put the shared library to and run the appropiate Makefile. (e.g: make -f Makefile.linux).
Currently supported are:
If you cannot download Dir.jar because your browser complains about failing security checks, press shift while clicking to bypass smart update.