Argh, now I just cannot help myself not to blurt this out. One of the most frustrating small knacks I have come up against lately.
At work, I need to rebuild one customer specific Java web application using JDK 1.6 to match the base product change to target 1.6.
So I login to the build machine, check out that there is JDK 1.6 installed, update the Antbuild.xml with new JDK location + target and start the build...
...
compile:
[echo] ============================================================
[echo] Compiling source files
[javac] Compiling 12 source files to C:\projects\xxx\build\classes
[javac] javac: invalid target release: 1.6
[javac] Usage: javac
[javac] where possible options include:
[javac] -g Generate all debugging info
...
WHAT??!! I scratch my head and try editing all the related properties and build script files - trying out all combinations of parameters ...to no avail.
Ok... Google gives me a load of links to discussions like this one on stackoverflow:
Q:
problem in ant build
...
ant source and target to 1.6 en variable path to jdk 1.6
A:
It might be useful for some to know that ant looks at the JAVA_HOME
variable when deciding which Java version to use
A:
Check the used Java-version with adding following line to your
target (at the beginning): ...
etc
Well... In our ant script we tell the exact path to the javac executable, so it cannot be that - changing the JAVA_HOME obviously has no effect in this case either.
So to debug the issue I fire up a command prompt and try it manually:
C:\>%JAVA_HOME%\bin\javac -version
javac 1.6.0_21
javac: no source files
Usage: javac
where possible options include:
...
C:\>%JAVA_HOME%\bin\javac -target 1.6
javac: invalid target release: 1.6
Usage: javac
where possible options include:
...
BOOM!! There it is - the same error message outside of Ant.
Hmm, now lets try on another JDK 1.6 update:
C:\>set JAVA_HOME=C:\Progra~1\Java\jdk1.6.0_45
C:\>%JAVA_HOME%\bin\javac -version
javac 1.6.0_45
C:\>%JAVA_HOME%\bin\javac -target 1.6
javac: no source files
Usage: javac
use -help for a list of possible options
...so there have been some broken JDK build(s) out there and the solution is to upgrade the JDK. Phew.
Luckily I get paid for this ;) ...and the Oracle JDK8 for Raspberry Pi (well, "Linux ARM v6/v7 Hard Float ABI") is still pretty awesome :D
Out of curiosity, arising from a discussion on the Raspberry Pi forum, I did some micro benchmarking of C, Java and Python programming languages on Raspberry Pi. The application loops through numbers from 3 to 10000 and checks whether it is a prime number. I tried my best to make the code as close the same in all three languages (even not using boolean types) and eliminate any interference like console output. Also I did repeat the tests multiple times; seeing only some milliseconds deviation between runs.
Python code:
result = 0
result |= 2
for i in range(3,10001):
prime = 1
for j in range(2, i):
k = i/j
l = k*j
if l == i:
prime = 0
if prime == 1:
result |= i
print result
$ time python prime2.py
16383
real 8m25.081s
user 8m7.960s
sys 0m1.230s
$ python --version
Python 2.7.3
...yes, that is 8 and a half minutes.
C code (repeats the test function 10 times to match Java...):
#include <stdio.h>
int test() {
int result = 0;
result |= 2;
int i;
for (i=3;i<=10000;i++) {
int prime = 1;
int j;
for (j=2;j<i;j++) {
int k = i/j;
int l = k*j;
if (l==i) prime = 0;
}
if (prime) result |= i;
}
printf("%i\n", result);
}
int main() {
int i;
for (i = 0; i < 10; i++) {
test();
}
}
Saved as prime2.c, compiled with gcc -O2 -o prime2 prime2.c (with typical optimisation level 2) and ran:
$ time ./prime2
16383
16383
16383
16383
16383
16383
16383
16383
16383
16383
real 0m35.957s
user 0m35.780s
sys 0m0.070s
$ gcc --version
gcc (Debian 4.6.3-14+rpi1) 4.6.3
...which is 36 seconds for 10 rounds = less than 4 seconds for the same one round as in Python... (gcc (Debian 4.6.3-14+rpi1) 4.6.3)
Java code (repeats the test function 10 times to eliminate the effect of virtual machine start up time and possibly give the Hotspot compiler a chance to kick in):
public class Prime2 {
public static void main(String [] args) {
for (int i = 0; i < 10; i++) {
test();
}
}
public static void test() {
int result = 0;
result |= 2;
for (int i=3;i<=10000;i++) {
boolean prime = true;
for (int j=2;j<i;j++) {
int k = i/j;
int l = k*j;
if (l==i) prime = false;
}
if (prime) result |= i;
}
System.out.println(result);
}
}
Saved as Prime2.java, compiled with javac Prime2.java and ran:
$ time java Prime2
16383
16383
16383
16383
16383
16383
16383
16383
16383
16383
real 0m33.490s
user 0m33.130s
sys 0m0.240s
$ java -version
java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b36e)
Java HotSpot(TM) Client VM (build 25.0-b04, mixed mode)
...which is pretty impressive - even slightly faster than C - the Oracle guys have done a good job with optimising the Java platform for RPi.
Of course this is just a micro benchmark and one cannot draw too definite conclusions from the results. Also there are other aspects (accessibility, productivity, availability of domain specific libraries etc.) to consider when choosing a programming language.