Posts Tagged ‘java’

The while-else-loop

Sometimes, “while” and “if” are interchangeable, for example while if you are “iterating” over a collection that will only contain one or zero elements. In Java, both constructs have the same syntax, so I often find myself switching from one to the other.

Yesterday, I didn’t notice that my “if” construct already had an “else” branch, and so I created a while-else-loop. It took Eclipse like 10 seconds to realize that there’s something wrong, so when I saw my error after about 5 seconds, I instantly though “maybe that’s valid Java, and nobody ever noticed…”. Well it isn’t, but now I’m asking: why? And while I’m talking about the while-else-loop, what about for-else?

Often, you find yourself dealing with empty collections manually, like this:

Collection<Stuff> myStuff = getStuff();
if(myStuff.isEmpty())
{
    System.out.println("I've got no stuff.");
}
else
{
    for(Stuff s : myStuff)
    {
        System.out.println("I've got " + s.getDescription());
    }
}

Wouldn’t it be nice to have something like

Collection<Stuff> myStuff = getStuff();
for(Stuff s : myStuff)
    System.out.println("I've got " + s.getDescription());
else
    System.out.println("I've got no stuff.");

That would be pretty neat. But once you think about common loop idioms, there’s even more to invent.

And sometimes, you have to do something before the first and after the last line, but not if there are no lines. Or you have to do something between the lines, or just before the last one. Imagine your collections contains {socks,cups,dust,chocolate,nails} and you want to create an output like this:

I’ve got socks, cups, dust, chocolate and nails.

Normally, this involves heavy if-else action, and counting, like that:

Collection<Stuff> myStuff = getStuff();
if (myStuff.isEmpty()) {
	System.out.println("I've got no stuff.");
} else {
	int size = myStuff.size();
	int counter = 0;
	System.out.print("I've got ");
	for (Stuff s : myStuff) {
		System.out.print(s.getDescription());
		if (counter < size - 1)
			System.out.print(", ");
		else
			System.out.print(" and ");
		counter++;
	}
	System.out.print(".n");
}

Imagine writing it like that:

Collection<Stuff> myStuff = getStuff();
iterate(Stuff s : myStuff)
{
    before:
        System.out.print("I've got ");
    for:
        System.out.print(s.getDescription());
    between:
        System.out.print(", ");
    beforelast:
        System.out.print(" and ");
    after:
        System.out.print(".n");
    empty:
        System.out.print("I've got no stuff.n");
}

For While it may be overkill to put this into the Java language, I think it might be the right time for me to look into a language that has the degree of flexibility that allows me to introduce such constructs myself, without patching the compiler.

PS: Any ideas how to get syntax highlighting  into wordpress, given the fact that I want to use it for non-existing syntax constructs?

Using Tomcat (or anything Java) on a virtual server

When it comes to serving web pages, two technical trends (among others) are prevalent: virtual servers and server side Java. To the end user, both are completely transparent, and even the server administrator might forget the fact that his server is virtual, because from experience he can tell that it behaves exactly as a physical server. It seems only natural (not even worth mentioning) to combine both trends.

In fact, this is not as easy as you might guess. Lets say you have a virtual server, running Ubuntu 9.04, and have installed sun-java6-jdk, and decompressed tomcat-6.0.18 somewhere.  The most trivial way to start it is

tomcat-6.0.18/bin/startup.sh

which is likely to tell you something like

Using CATALINA_BASE: /(...)/tomcat-6.0.18
Using CATALINA_HOME:   /(...)/tomcat-6.0.18
Using CATALINA_TMPDIR: /(...)/tomcat-6.0.18/temp
Using JRE_HOME:       /usr/lib/jvm/java-1.6.0-sun

While this might seem as if the server was started successfully, nothing really happened. A look into /(…)/tomcat-6.0.18/logs/catalina.out might show something like

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

This is due to the way memory management is handled on virtual servers, which you can read here. It has nothing to with the actual amount of RAM that Tomcat needs, it also appears that a simple command like “java -version” tries to allocate more memory then it is allowed to (284 MB on my vServer). Several sites recommend to set the -Xmx option when starting Java, mostly by modifying scripts which are not made to be modified. Some others advise changing /etc/java-1.5.0-sun/jvm.cfg to prefer the client VM over the server VM, or even to delete the server VM and symlink it to the client version.

Not only is it highly absurd that you have to use a client VM on a server just because the server is not capable of running the server VM, but it also is impossible, because Java 6 seams to have no client implementation on 64 bit processors – and of course virtual servers run on 64 bit machines (mine has at least 44 GB of RAM, how would it handle this on 32 bit?).

Using -Xmx seems to work, even though you do not want to change each and every script that calls java or javac. To encompass this, you can set the environment variable JAVA_OPTS to something like JAVA_OPTS=”-Xms10m -Xmx256m”, which is definitely picked up by Tomcat, and maybe used by other scripts which run java or javac. Sadly, many scripts do not, and there seems to be not way to make java “just run” on a virtual server.

With the proper options, java does run, but Tomcat does not. It keeps on saying

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

I started writing this blog post hoping that I would conclude with a working solution, but as it seems right now, I just cannot find one. I will keep trying, possibly not only searching the web but also posting questions like I did on serverfault.com and in the end I will update this post to reflect the solution.

One more note: whil this works for calls to the “java” binary, it does not for “javac”, which does not directly accept -Xms and -Xmx. You have to use -J-Xms and -J-Xmx instead.

Return top

Hallo!

Ich bin Lena und schreibe hier über alles, was mir gerade wichtig ist. In letzter Zeit also Frauenrechte, Gesellschaft, Politik, Transsexualität, Privates, Computerzeugs... Ich freue mich über konstruktive Kommentare!

Blog abonnieren

Email: