Paul's Raspberry Pi Journal

From Resin 4.0 Wiki

(Difference between revisions)
Jump to: navigation, search
 
(26 intermediate revisions by one user not shown)
Line 1: Line 1:
<font color="black face="comic sans ms" size="3">
+
{{Embedded}} {{Raspi}}
  
== Paul's Raspberry Pi Journal ==
+
<font color="black face="tahoma" size="3" color="#009">
  
=== Intro ===
+
= Intro =
  
 
Hi!  I'm [http://www.caucho.com/about/ Paul Cowan], a software engineer at [http://www.caucho.com/ Caucho Technology].  Caucho is primarily a Java EE application server vendor.  Our application server is called [http://www.caucho.com/resin-application-server/ Resin].  I mostly write Java code, but I'm also a computer hobbyist and like to tinker with anything techie.
 
Hi!  I'm [http://www.caucho.com/about/ Paul Cowan], a software engineer at [http://www.caucho.com/ Caucho Technology].  Caucho is primarily a Java EE application server vendor.  Our application server is called [http://www.caucho.com/resin-application-server/ Resin].  I mostly write Java code, but I'm also a computer hobbyist and like to tinker with anything techie.
  
During Caucho's last engineer meeting in San Francisco (October 2012), I brought up [http://www.raspberrypi.org/ Raspberry Pi] as an avenue we could explore for Resin.  It probably wouldn't directly sell Resin licenses, but it would be a great marketing vehicle.  Everybody like it, Caucho is cool like that, and so I'm off.
+
During Caucho's last engineer meeting in San Francisco (October 2012), I brought up [http://www.raspberrypi.org/ Raspberry Pi] as an avenue we could explore for Resin.  It probably wouldn't directly sell Resin licenses, but it would be a great marketing vehicle.  Everybody liked it, Caucho is cool like that, and so I'm off.
  
=== About Resin ===
+
= About Resin =
  
 
Resin is a fairly light-weight for an app server and embeds well.  It's really a nice platform on which to build just about anything in Java, since it can make just about any app HTTP enabled and handles all the mundane services like logging and you don't really want to have to deal with.  It also provides a dependency injection container... Now you may be asking "why do I can about dependency injection when I'm just playing around with hobby projects."  Well personally I pump out Java code much faster using dependency injection and just find it easier to write in that style.   
 
Resin is a fairly light-weight for an app server and embeds well.  It's really a nice platform on which to build just about anything in Java, since it can make just about any app HTTP enabled and handles all the mundane services like logging and you don't really want to have to deal with.  It also provides a dependency injection container... Now you may be asking "why do I can about dependency injection when I'm just playing around with hobby projects."  Well personally I pump out Java code much faster using dependency injection and just find it easier to write in that style.   
Line 15: Line 15:
 
Resin also includes [http://quercus.caucho.com/ Quercus, a Java based PHP interpreter].  I'm not really planning to make PHP a focus of this project, but it's handy to have available just in case.
 
Resin also includes [http://quercus.caucho.com/ Quercus, a Java based PHP interpreter].  I'm not really planning to make PHP a focus of this project, but it's handy to have available just in case.
  
=== About This Journal ===
+
= About This Journal =
  
 
The Raspberry Pi platform and community certainly seems to be evolving rapidly, but it still seems like there's not enough documentation out there.  In particular Java support is kinda spotty, and I haven't found anything on JEE on a Raspberry Pi.  So I'm going to document my experience in hope it is useful to other Java developers getting started with Raspberry Pi.   
 
The Raspberry Pi platform and community certainly seems to be evolving rapidly, but it still seems like there's not enough documentation out there.  In particular Java support is kinda spotty, and I haven't found anything on JEE on a Raspberry Pi.  So I'm going to document my experience in hope it is useful to other Java developers getting started with Raspberry Pi.   
  
=== Hardware ===
+
= Hardware =
  
 
* [http://www.newark.com/jsp/search/productdetail.jsp?sku=43W5302 Raspberry Pi Model B] board from [http://www.newark.com/ Newark Element 14] (Upgraded from 256 Mb model for free)
 
* [http://www.newark.com/jsp/search/productdetail.jsp?sku=43W5302 Raspberry Pi Model B] board from [http://www.newark.com/ Newark Element 14] (Upgraded from 256 Mb model for free)
Line 26: Line 26:
 
I ordered the Pi early in October, but it was backordered by about 4 weeks.  10/15 they sent me an email my order was upgraded for free from 256 Mb to the 512 Mb model.  It was delivered 10/18, so about 2 weeks early.
 
I ordered the Pi early in October, but it was backordered by about 4 weeks.  10/15 they sent me an email my order was upgraded for free from 256 Mb to the 512 Mb model.  It was delivered 10/18, so about 2 weeks early.
  
* [http://www.monoprice.com/products/product.asp?c_id=104&cp_id=10419&cs_id=1041902&p_id=2081&seq=1&format=2 HDMI to DVI adapter from [http://www.monoprice.com/ Monoprice]
+
* [http://www.monoprice.com/products/product.asp?c_id=104&cp_id=10419&cs_id=1041902&p_id=2081&seq=1&format=2 HDMI to DVI adapter] from [http://www.monoprice.com/ Monoprice]
 
* [http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10240&cs_id=1024008&p_id=3992&seq=1&format=2 HDMI cable]
 
* [http://www.monoprice.com/products/product.asp?c_id=102&cp_id=10240&cs_id=1024008&p_id=3992&seq=1&format=2 HDMI cable]
  
 
I use an IOGear DVI KVM so monitor and keyboard aren't a problem.  In fact the KVM combines the mouse and keyboard into a single USB cable, so that leaves me a free USB port on the RasPi.  However I needed an adapter and HDMI cable.  Monoprice is great for this kind of stuff.
 
I use an IOGear DVI KVM so monitor and keyboard aren't a problem.  In fact the KVM combines the mouse and keyboard into a single USB cable, so that leaves me a free USB port on the RasPi.  However I needed an adapter and HDMI cable.  Monoprice is great for this kind of stuff.
  
* PNY 8 Gb SD card from BJ's (I think... I stoled it from the family camera :) )
+
* PNY 8 Gb SD card from BJ's... I think, I stolen from the family camera :)  
 
* MicroUSB cable and AC adapter from my Kindle
 
* MicroUSB cable and AC adapter from my Kindle
 +
  
 
{|
 
{|
Line 41: Line 42:
 
|}
 
|}
  
=== Getting Started ===
+
= Getting Started =
 +
 
 +
I started with [http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html this write up from Oracle] and the [http://www.raspberrypi.org/downloads Raspberry Pi downloads page].  It becomes apparent pretty quickly that there's a float-point compatibility issue with Java on Raspberry Pi.  Here's a summary of what I understand regarding the state of Raspberry Pi operating systems and Java support as of 11/2012:
 +
 
 +
== OS ==
 +
 
 +
* The "official" distro is Raspbian Wheezy, which is offered for download on on [http://www.raspberrypi.org/downloads raspberrypi.org/downloads]
 +
* This distro is variant of Raspbian Wheezy from [http://www.raspbian.org/ raspbian.org] but with a light-weight desktop, Midori web browser, and a few other development extra specifically for Raspberry Pi
 +
* Raspbian Wheezy is a variant of Debian Wheezy but compiled for ARM processor with optimization specifically for Raspberry Pi (hardware floating-point)
 +
* [http://wiki.debian.org/DebianWheezy Debian Wheezy]  is the "testing" distro of Debian, while [http://wiki.debian.org/DebianSqueeze/ Debian Squeeze] is the current stable release
 +
* There are [http://elinux.org/RPi_Distributions#Available_Distributions various other linux distros supporting ARM processor]
 +
 
 +
I should mention that my understand is you can't just use any ARM linux distro straight up.  The boot sequence for a Raspberry Pi dependent on the SD card.  It actually boots from a small RISC core on the GPU, but the GPU firmware is loaded from the SD card.  [http://elinux.org/RPi_Software#Overview More here].
 +
 
 +
This article helps if you're a little lost like I was: [http://www.informit.com/articles/article.aspx?p=1620207&seqNum=4 Understanding ARM Architectures].
 +
 
 +
== Java Compatability ==
 +
 
 +
* Currently NO Java distro that I'm aware of has support for Raspberry Pi's hardware floating point unit (hard-float)
 +
* Therefore we need OS distro that support soft-float, ARMv6, little-endian
 +
* The Oracle article is discussing using Debian Squeeze, which I suspect is because it was the best distro available at the time with soft floating-point support.
 +
* However there is now a [http://www.raspberrypi.org/downloads Soft-float Debian wheezy Rasbian image] available at [http://www.raspberrypi.org/downloads raspberrypi.org/downloads], so I'm going to try that to start out
 +
 
 +
Honestly I don't want a desktop at all and would like fast boot, so the Arch Linux distro appeals to me.  (Note to try it later.)
 +
 
 +
= Imaging =
 +
 
 +
There's a Fedora installer that sounds interesting, but I'm running on OSX.  The instructions on the [http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html Oracle article] are based on Linux, but there's also [http://elinux.org/RPi_Easy_SD_Card_Setup decent instructions here].  Basically the distro is a raw SD card image, containing partitions, so you have to write it directly to the SD card in raw form.
 +
 
 +
* Inserted the SD card into my MacBook's SD Slot
 +
* Ran Search->Disk Utility
 +
* SD card is listed as 8.01 GB APPLE SD Card...
 +
* Erase->MS-DOS(FAT), Name: RASPI
 +
* Erase
 +
 
 +
Next, I tried [https://github.com/exaviorn/RasPiWrite RasPiWrite] and failed.  The script doesn't even run due to syntax errors.  I'm not going to debug a Python script, so that fails the 10-minute test.
 +
 
 +
Now following [http://elinux.org/RPi_Easy_SD_Card_Setup "Easy Way" instructions] from the Raspberry Pi wiki...
 +
 
 +
* df -h reveals my SD card mount simply enough:
 +
 
 +
/dev/disk1s1  7.4Gi  624Ki  7.4Gi    1%    /Volumes/RASPI
 +
 
 +
$ sudo diskutil unmount /dev/disk1s1
 +
Password:
 +
Volume RASPI on disk1s1 unmounted
 +
 
 +
$ sudo dd bs=1m if=~/Downloads/2012-08-08-wheezy-armel.img of=/dev/rdisk1
 +
1850+0 records in
 +
1850+0 records out
 +
1939865600 bytes transferred in 136.071302 secs (14256243 bytes/sec)
 +
 
 +
Well that looks like it worked!
 +
 
 +
[[File:Raspi-5.png]]
 +
 
 +
= First Boot =
 +
 
 +
The Raspberry Pi booted right into a blue menu screen called [http://elinux.org/RPi_raspi-config raspi-config] that lets you configure basic OS settings. 
 +
 
 +
* The first thing I did was hit EXPAND-ROOTFS to use of the rest of the free space on the SD card
 +
* After a "sudo reboot" it printed logs about resizing the root file system.  That took a few minutes but seems work fine.
 +
* I configured, locale, timezone, enabled SSHD, and set the the desktop to NOT start on boot
 +
* Finished, reboot
 +
* The pi is showing up on my network, SSH works, looks good to go!
 +
 
 +
pi@raspberrypi ~ $ df -h
 +
Filesystem      Size  Used Avail Use% Mounted on
 +
rootfs          7.3G  1.3G  5.7G  19% /
 +
/dev/root      7.3G  1.3G  5.7G  19% /
 +
tmpfs            22M  228K  22M  2% /run
 +
tmpfs          5.0M    0  5.0M  0% /run/lock
 +
tmpfs            44M    0  44M  0% /tmp
 +
tmpfs            10M    0  10M  0% /dev
 +
tmpfs            44M    0  44M  0% /run/shm
 +
/dev/mmcblk0p1  56M  35M  22M  61% /boot
 +
 
 +
The [http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html Oracle article] goes into a lot of detail about setting up DHCP, local. time-zone, etc e which doesn't seem necessary since Raspbian provides raspi-config.
 +
 
 +
Hmm, I'm noticing the OS is only seeing 256 Mb instead of 512....  They told me I was sent an upgraded model to the 512 Mb.
 +
 
 +
pi@raspberrypi ~ $ free -h
 +
            total      used      free    shared    buffers    cached
 +
Mem:          216M        48M      168M        0B      9.0M        23M
 +
-/+ buffers/cache:        15M      200M
 +
Swap:          99M        0B        99M
 +
 
 +
pi@raspberrypi ~ $ cat /proc/cpuinfo
 +
Processor : ARMv6-compatible processor rev 7 (v6l)
 +
BogoMIPS : 697.95
 +
Features : swp half thumb fastmult vfp edsp java tls
 +
CPU implementer : 0x41
 +
CPU architecture: 7
 +
CPU variant : 0x0
 +
CPU part : 0xb76
 +
CPU revision : 7
 +
 
 +
Hardware : BCM2708
 +
Revision : 0005
 +
Serial : 00000000edc79c8a
 +
 
 +
(Emailed Newark customer service about it, have not heard back yet).
 +
 
 +
= Getting Oracle JRE 7 Running =
 +
 
 +
As I mentioned above, there's no Raspi hardware floating-point support in Java (yet?).  I'm planning to install Oracle/OpenJDK/JRE to do some testing and see what runs best.  Resin is not fully functional with a JRE, it can't compile JSPs...
 +
 
 +
Downloading ARMv6/7 Linux - Headless EABI, VFP, SoftFP ABI, Little Endian1 (ejre-7u6-fcs-b24-linux-arm-vfp-client_headless-10_aug_2012.tar.gz) from [http://www.oracle.com/technetwork/java/embedded/downloads/javase/index.html Oracle].
 +
 
 +
(Hmm, it takes like 2 minutes to scp 32Mb to the Pi from OSX...  That troubling.  Not sure if it's the write to SD card speed or network.)
 +
 
 +
Unziped, untar, there's no installer.  There's only 2 files in bin, java and keytool.  I'm going to setup Java like a typical linux install by moving the extracted dir to /usr/ejre1.7.0_06 and symlink to /usr/java and link the executables into /usr/bin.
 +
 
 +
pi@raspberrypi ~ $ which java
 +
/usr/bin/java
 +
pi@raspberrypi ~ $ java -version
 +
java version "1.7.0_06"
 +
Java(TM) SE Embedded Runtime Environment (build 1.7.0_06-b24, headless)
 +
Java HotSpot(TM) Embedded Client VM (build 23.2-b09, mixed mode)
 +
 
 +
= Getting Resin Running =
 +
 
 +
I'm going to focus on the open-source Resin Servlet Container for this project.
 +
 
 +
wget http://www.caucho.com/download/resin-4.0.32.zip
 +
 
 +
Extracting the zip was fast, but the whole system then stopped responding for a few seconds afterwards...  I guessing it's write buffering to the SD card and has to wait for the hardware to catchup. (?)
 +
 
 +
Trying a configure/make/make install of Resin:
 +
 
 +
./configure
 +
 +
configure: error:
 +
 +
    *** Can't find JNI directory in JAVA_HOME=/usr/java
 +
    *** JNI is expected in /usr/java/include/linux
 +
 
 +
Crap... this Java distro does not include the Java headers.  We won't be able to compile Resin native libraries with this Java, maybe one of the others will have headers.  Resin will still work in pure Java mode.
 +
 
 +
Let's try with:
 +
 
 +
./configure --disable-jni
 +
 
 +
Configure succeeds that time.  "make" succeeds.  "sudo make install" succeeds. 
 +
 
 +
Resin is installed to /etc/init.d, /etc/resin, /usr/local/share/resin, /var/resin, etc.
 +
 
 +
pi@raspberrypi /var/resin $ resinctl start
 +
Resin/4.0.32 launching watchdog at 127.0.0.1:6600
 +
java.io.FileNotFjava.io.FiloundExceNotFoeption:undExce /var/ption: /log/resivar/logn/watch/resin/dog-manwatchdoager.log g-manage(Permissr.log (Pion deermissionied)
 +
n denied)
 +
at java.io.FileOutputStream.open(Native Method)
 +
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
 +
at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
 +
at com.caucho.vfs.FilePath.openAppendImpl(FilePath.java:586)
 +
at com.caucho.vfs.Path.openAppend(Path.java:1229)
 +
at com.caucho.boot.WatchdogManager.<init>(WatchdogManager.java:143)
 +
at com.caucho.boot.WatchdogManager.main(WatchdogManager.java:1009)
 +
Resin/4.0.32 started -server 'app-0' with watchdog at 127.0.0.1:6600
 +
 
 +
Well that's a weird error... I forgot to start with sudo, retry.
 +
 
 +
pi@raspberrypi /var/log/resin $ sudo resinctl start
 +
Resin/4.0.32 launching watchdog at 127.0.0.1:6600
 +
Resin/4.0.32 started -server 'app-0' with watchdog at 127.0.0.1:6600
 +
 
 +
That's better.  It only took about 15 seconds to startup, not too bad.  Checking the logs...
 +
 
 +
[2012/12/04 14:14:31.094] {main} Unable to find native library 'resin_os' for com.caucho.bootjni.JniProcess. Resin expects to find this library in:
 +
                                  (Unix) /usr/local/share/resin-4.0.32/libexec/libresin_os.so
 +
                                On Unix, run ./configure --prefix=`pwd`; make; make install.
 +
                               
 +
                                The JVM exception was: java.lang.UnsatisfiedLinkError: no resin_os in java.library.path
 +
 
 +
watchdog-manager.log is complaining about missing native libraries, but that's expected.
 +
 
 +
[12-12-04 14:15:12.478] {main} Resin-4.0.32 (built Mon, 01 Oct 2012 03:05:04 PDT)
 +
[12-12-04 14:15:12.482] {main}
 +
[12-12-04 14:15:12.485] {main} Linux 3.2.27+ arm
 +
[12-12-04 14:15:12.489] {main} Java(TM) SE Embedded Runtime Environment 1.7.0_06-b24, UTF-8, en
 +
[12-12-04 14:15:12.493] {main} Java HotSpot(TM) Embedded Client VM 23.2-b09, 32, mixed mode, Oracle Corporation
 +
 
 +
Cool!
 +
 
 +
Trying http://raspberrypi:8080/ 
 +
 
 +
500 Servlet Exception
 +
 +
javac compiler is not available in Java(TM) SE Embedded Runtime Environment
 +
1.7.0_06-b24. Check that you are using the JDK, not the JRE.
 +
 
 +
Well that's expect also, we're using a JRE so no JSP compiler...
 +
 
 +
Trying http://raspberrypi:8080/resin-doc/  That works!  Why?...  XTP is not compiled! 
 +
 
 +
Trying http://raspberrypi:8080/resin-admin  That works too!  PHP is not compiled either!
 +
 
 +
Admin account generation worked.  Resin restart took 45 seconds, Ugh.
 +
 
 +
[[File:Raspi-6.png]]
 +
 
 +
= Getting OpenJDK 7 Running =
 +
 
 +
Attempting to install OpenJDK from the package:
 +
 
 +
apt-get install openjdk-7-jdk
 +
 
 +
Nice! That works!
 +
 
 +
root@raspberrypi:~# which java
 +
/usr/bin/java
 +
root@raspberrypi:~# cd /usr/bin/
 +
root@raspberrypi:/usr/bin# ls -l java
 +
lrwxrwxrwx 1 root root 22 Dec  4 16:21 java -> /etc/alternatives/java
 +
root@raspberrypi:/usr/bin# cd /etc/alternatives/
 +
root@raspberrypi:/etc/alternatives# ls -l java
 +
lrwxrwxrwx 1 root root 46 Dec  4 16:21 java -> /usr/lib/jvm/java-7-openjdk-armel/jre/bin/java
 +
root@raspberrypi:/etc/alternatives# cd /usr/lib/jvm/
 +
root@raspberrypi:/usr/lib/jvm# ls -l
 +
total 8
 +
lrwxrwxrwx 1 root root  20 Oct 18 03:13 java-1.7.0-openjdk-armel -> java-7-openjdk-armel
 +
drwxr-xr-x 7 root root 4096 Dec  4 16:19 java-7-openjdk-armel
 +
drwxr-xr-x 3 root root 4096 Dec  4 16:16 java-7-openjdk-common
 +
 
 +
So OpenJDK uses the Linux Alternatives project... (Not a big fan of alternatives but I'll deal.)  It install armel and common, not sure what that's about.
 +
 
 +
Starting Resin with OpenJDK...
 +
 
 +
[12-12-05 20:05:52.793] {main}
 +
[12-12-05 20:05:52.817] {main} Resin-4.0.32 (built Mon, 01 Oct 2012 03:05:04 PDT)
 +
[12-12-05 20:05:52.826] {main}
 +
[12-12-05 20:05:52.838] {main} Linux 3.2.27+ arm
 +
[12-12-05 20:05:52.872] {main} OpenJDK Runtime Environment 1.7.0_03-b21, UTF-8, en
 +
[12-12-05 20:05:52.887] {main} OpenJDK Zero VM 22.0-b10, 32, mixed mode, Oracle Corporation
 +
 
 +
Ok it start, but wow it's really slow.  ResinBoot itself took like 20 seconds, and it must have been 3 minutes before port 8080 was bound.  http://raspberrypi:8080/ loads to, but it took like 40 seconds. 
 +
 
 +
Doing some research, I see there's 3 different VM's built into OpenJDK, that's interesting.  Here's the 3:
 +
 
 +
* [http://openjdk.java.net/projects/zero/ Zero VM]
 +
* [http://www.cacaojvm.org/ Cacao VM]
 +
* [http://jamvm.sourceforge.net/ Jam VM]
 +
 
 +
 
 +
The /usr/lib/jvm/java-7-openjdk-armel/docs/README.Debian explains this in detail:
 +
 
 +
The OpenJDK build is configured --with-additional-vms to build with
 +
different virtual machines.  The original implementation of the hotspot
 +
VM is only available on the amd64, i386, lpia and sparc architectures.
 +
Other VM's are CACAO, providing a just in time compiler on several
 +
architectures (although the VM implementation is incomplete), and Zero,
 +
providing a byte code interpreter for every architecture.  On some
 +
architectures Zero is built with JIT support using shark (still considered
 +
experimental).
 +
 +
To use a different VM other than the default, use
 +
 +
        java -cacao|-zero|-shark
 +
 +
or for the java tools, use
 +
 +
        <tool name> -J-cacao|-J-zero|-J-shark.
 +
 +
The zero build on the ix86 architectures is built with shark (just in time
 +
compiler); to use the zero build without shark support, use the `-Xint'
 +
option to operate in interpreted-only mode.
 +
 +
On some architectures (currently armel and powerpc, when built against
 +
llvm-2.6) which use ther zero vm as the default, the openjdk-7-jre-zero
 +
package contains the shark vm.
 +
 
 +
To change the default permanently, edit /etc/java-7-openjdk/jvm.cfg.
 +
 +
The CACAO VM can be found in the icedtea-7-jre-cacao package, the Zero/Shark
 +
VM can be found in the openjdk-7-jre-zero package (on the architectures
 +
where the Hotspot VM is available).
 +
 +
So Zero is the default, which is interpreted mode, so that could account for the slow performance I was seeing.  Sounds like I need to do some performance testing.
 +
 
 +
I see OpenJDK includes headers!
 +
 
 +
root@raspberrypi:/usr/lib/jvm/java-7-openjdk-armel/include# ls -l
 +
total 212
 +
-rw-r--r-- 1 root root 21079 Oct 18 03:05 classfile_constants.h
 +
-rw-r--r-- 1 root root  9544 Oct 18 03:05 jawt.h
 +
lrwxrwxrwx 1 root root    15 Oct 18 03:13 jawt_md.h -> linux/jawt_md.h
 +
-rw-r--r-- 1 root root  7206 Oct 18 03:05 jdwpTransport.h
 +
-rw-r--r-- 1 root root 74663 Oct 18 03:05 jni.h
 +
lrwxrwxrwx 1 root root    14 Oct 18 03:13 jni_md.h -> linux/jni_md.h
 +
-rw-r--r-- 1 root root  4771 Oct 18 03:05 jvmticmlr.h
 +
-rw-r--r-- 1 root root 78425 Oct 18 03:05 jvmti.h
 +
drwxr-xr-x 2 root root  4096 Dec  4 16:19 linux
 +
 
 +
So I wonder if Resin will compile on Raspberry Pi now... Trying...
 +
 
 +
./configure works!
 +
 
 +
Resin Configuration Summary:
 +
 +
  RESIN      : 4.0.32
 +
    home      : /usr/local/share/resin-4.0.32
 +
    root      : /var/resin
 +
    conf      : /etc/resin
 +
    log      : /var/log/resin
 +
    plugins  : common resin_os
 +
    init      : /etc/init.d/resin
 +
 +
  JAVA_HOME  : /usr/lib/jvm/java-7-openjdk-armel/jre/bin/../..
 +
 +
  JNI        : 32-bit
 +
    include      : -I/usr/lib/jvm/java-7-openjdk-armel/jre/bin/../../include
 +
    CFLAGS        :
 +
    cflags_shlib  : -fpic
 +
    ld_shlib      : gcc
 +
    ldflags_shlib : -shared -fPIC -m32
 +
    libs_shlib    :
 +
    epoll() for keepalives
 +
 
 +
But make fails:
 +
 
 +
gcc -g -O2 -DEPOLL -D_POSIX_PTHREAD_SEMANTICS -pthread -fPIC -fno-omit-frame-pointer -O2 -DHAS_SOCK_TIMEOUT -DHAS_SENDFILE -DHAS_SPLICE -DPOLL -DHAS_JVMTI  -fPIC -m32 -DRESIN_HOME=\"/usr/local/share/resin-4.0.32\" -I/usr/include -I/usr/lib/jvm/java-7-openjdk-armel/jre/bin/../../include  -I../common -DCPU=\"armv6l\" -DOS=  -c -o boot.o boot.c
 +
cc1: error: unrecognized command line option -m32
 +
 
 +
So gcc on Raspberry Pi doesn't like -m32... It's a 32-bit architecture.  I can probably work out the proper compilation flags but will put that off until later.  For now we'll continue to run Resin in java-only mode.
 +
 
 +
= JVM Performance Testing =
 +
 
 +
* See [[Java On Raspberry Pi Performance]]
 +
 
 +
= Resin on OpenJDK =
 +
 
 +
Resin is automatically adding -server to the Resin command line during startup.  -server implies -zero, so I can't get it to use -cacao or -jamvm at all without changes.
 +
 
 +
I'm staring a [[Resin Changes To Support Raspberry Pi]] list.
 +
 
 +
= Oracle JDK on Raspberry Pi =
 +
 
 +
I'm quite interested in trying [http://pi4j.com/ Pi4J], which looks like a great little Java wrapper around a native library called [https://projects.drogon.net/raspberry-pi/wiringpi/ WiringPi] that lets you work with the Raspi hardware directly (GPIO, serial port, etc)
 +
 
 +
The maintainer of Pi4J has a decent write on [http://www.savagehomeautomation.com/pi-jdk Raspberry Pi - Installing Oracle Java Development Kit (JDK 1.7.0u6)].  So reading that I come to find out there IS an [http://www.oracle.com/technetwork/java/javase/downloads/index.html  Oracle JDK that works on Raspberry Pi]!  (WTF Oracle?  Why isn't this listed under "Java Embedded".  I guess because the "embedded" version is stripped down to make the size smaller.)  Anyway, [http://www.oracle.com/technetwork/java/javase/downloads/index.html visit the Oracle downloads page], Java SE 7u10, JDK, there's a version available for "Linux ARM v6/v7 Soft Float ABI".  That's what we need... Now to redo my [[Java On Raspberry Pi Performance]] tests, again.
 +
 
 +
= Resin on Oracle JDK =
 +
 
 +
Unfortunately I've hit a wall with Resin in it's current state.  Resin automatically adds "-server" to the server startup command, and the JDK apparently won't run on Raspberry Pi with -server.  It complains about requiring and ARMv7 chip, but the Pi is v6...  (Resin embed may work.)
 +
 
 +
pi@raspberrypi ~/resin-4.0.32 $ /usr/java/bin/java -jar lib/resin.jar start
 +
Resin/4.0.32 launching watchdog at 127.0.0.1:6600
 +
Error occurred during initialization of VM
 +
Server VM is only supported on ARMv7+ VFP
 +
 
 +
Adding "remove -server" to the [[Resin Changes To Support Raspberry Pi]] list, and starting work on the changes to Resin 7.
 +
 
 +
= Resin Lite =
 +
 
 +
I'm coming back to this after a few weeks of holidays, distractions, bug fixes, and various other work...  I've created a special cut of our next version of Resin, Resin 7, called "Resin Lite".  Resin Lite is a single jar .war runner.  To be honest it's no very "lite" yet, but at least it should run better on RasPi since it won't add -server automatically.
 +
 
 +
=== Resin Lite on Zero ===
 +
 
 +
Resin starts on Zero with exceptions but appears to run OK.  I get a response to a servlet.  Performance is slow.  Log below...
 +
 
 +
pi@raspberrypi ~/resin-lite $ java -zero -jar resin-lite.jar webtest.war
 +
ResinLite starting at Tue, 08 Jan 2013 13:53:11 -0500 (EST)
 +
13-01-08 13:54:44.881 [main] INFO ResinSystem -
 +
13-01-08 13:54:44.890 [main] INFO ResinSystem - Resin-7.0.s130102 (built Wed, 02 Jan 2013 06:01:05 EST)
 +
13-01-08 13:54:44.896 [main] INFO ResinSystem -
 +
13-01-08 13:54:44.903 [main] INFO ResinSystem - Linux 3.2.27+ arm
 +
13-01-08 13:54:44.909 [main] INFO ResinSystem - OpenJDK Runtime Environment 1.7.0_03-b21, UTF-8, en
 +
13-01-08 13:54:44.916 [main] INFO ResinSystem - OpenJDK Zero VM 22.0-b10, 32, mixed mode, Oracle Corporation
 +
13-01-08 13:54:44.922 [main] INFO ResinSystem -
 +
13-01-08 13:54:44.931 [main] INFO ResinSystem - user.name  = pi
 +
13-01-08 13:54:47.206 [main] INFO ServletService -
 +
13-01-08 13:54:47.213 [main] INFO ServletService - resin.home = /home/pi/resin-lite
 +
13-01-08 13:54:47.219 [main] INFO ServletService - resin.root = /home/pi/resin-lite
 +
13-01-08 13:54:47.232 [main] INFO ServletService - resin.conf = /home/pi/resin-lite/conf/resin.conf
 +
13-01-08 13:54:47.236 [main] INFO ServletService -
 +
13-01-08 13:54:47.243 [main] INFO ServletService - server    = 127.0.0.1:-1 (:default)
 +
13-01-08 13:54:47.249 [main] INFO ServletService - stage      = production
 +
13-01-08 13:54:49.206 [main] INFO Host - Host[production/host/default] active
 +
13-01-08 13:54:49.225 [main] INFO ServletService - ServletService[id=default,cluster=] active
 +
13-01-08 13:54:49.257 [main] INFO NetworkListenSystem -
 +
13-01-08 13:54:49.397 [main] INFO TcpPort - http listening to *:8080
 +
13-01-08 13:54:50.740 [main] INFO NetworkListenSystem -
 +
13-01-08 13:54:50.785 [main] INFO Resin - ResinEmbeddedLite[id=default] started in 25338ms
 +
13-01-08 13:55:30.871 [main] WARNING WebApp - java.lang.InternalError: NYI
 +
                    at java.lang.invoke.AdapterMethodHandle.makeReturnConversion(AdapterMethodHandle.java:252)
 +
                    at java.lang.invoke.AdapterMethodHandle.makePairwiseConvert(AdapterMethodHandle.java:208)
 +
                    at java.lang.invoke.MethodHandleImpl.convertArguments(MethodHandleImpl.java:760)
 +
                    at java.lang.invoke.MethodHandleImpl.collectArguments(MethodHandleImpl.java:842)
 +
                    at java.lang.invoke.MethodHandleImpl.collectArguments(MethodHandleImpl.java:820)
 +
                    at java.lang.invoke.MethodHandle.asCollector(MethodHandle.java:889)
 +
                    at java.lang.invoke.AdapterMethodHandle$AsVarargsCollector.<init>(AdapterMethodHandle.java:568)
 +
                    at java.lang.invoke.AdapterMethodHandle.makeVarargsCollector(AdapterMethodHandle.java:556)
 +
                    at java.lang.invoke.MethodHandleImpl.findMethod(MethodHandleImpl.java:95)
 +
                    at java.lang.invoke.MethodHandles$Lookup.accessStatic(MethodHandles.java:592)
 +
                    at java.lang.invoke.MethodHandles$Lookup.findStatic(MethodHandles.java:587)
 +
                    at sun.invoke.util.ValueConversions$LazyStatics.<clinit>(ValueConversions.java:694)
 +
                    at sun.invoke.util.ValueConversions.buildArrayProducer(ValueConversions.java:1176)
 +
                    at sun.invoke.util.ValueConversions.varargsArray(ValueConversions.java:1164)
 +
                    at java.lang.invoke.MethodHandle.asCollector(MethodHandle.java:888)
 +
                    at java.lang.invoke.AdapterMethodHandle$AsVarargsCollector.<init>(AdapterMethodHandle.java:568)
 +
                    at java.lang.invoke.AdapterMethodHandle.makeVarargsCollector(AdapterMethodHandle.java:556)
 +
                    at java.lang.invoke.MethodHandleImpl.findMethod(MethodHandleImpl.java:95)
 +
                    at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:963)
 +
                    at com.caucho.config.attribute.SetterAttribute.<init>(SetterAttribute.java:55)
 +
                    at com.caucho.config.type.InlineBeanType.addProp(InlineBeanType.java:892)
 +
                    at com.caucho.config.type.InlineBeanType.introspectMethods(InlineBeanType.java:847)
 +
                    at com.caucho.config.type.InlineBeanType.introspect(InlineBeanType.java:607)
 +
                    at com.caucho.config.type.ConfigType.carefulIntrospect(ConfigType.java:68)
 +
                    at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:593)
 +
                    at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
 +
                    at com.caucho.config.attribute.CreateAttribute.getConfigType(CreateAttribute.java:75)
 +
                    at com.caucho.config.attribute.Attribute.isProgram(Attribute.java:74)
 +
                    at com.caucho.config.xml.XmlConfigContext.configureChildNode(XmlConfigContext.java:452)
 +
                    at com.caucho.config.xml.XmlConfigContext.configureAttribute(XmlConfigContext.java:324)
 +
                    at com.caucho.config.program.NodeBuilderChildProgram.inject(NodeBuilderChildProgram.java:82)
 +
                    at com.caucho.config.program.ContainerProgram.inject(ContainerProgram.java:88)
 +
                    at com.caucho.config.program.ConfigProgram.configure(ConfigProgram.java:107)
 +
                    at com.caucho.env.deploy.EnvironmentDeployController.configureInstance(EnvironmentDeployController.java:480)
 +
                    at com.caucho.env.deploy.EnvironmentDeployController.configureInstance(EnvironmentDeployController.java:59)
 +
                    at com.caucho.env.deploy.DeployController.startImpl(DeployController.java:684)
 +
                    at com.caucho.env.deploy.StartAutoRedeployAutoStrategy.startOnInit(StartAutoRedeployAutoStrategy.java:77)
 +
                    at com.caucho.env.deploy.DeployController.startOnInit(DeployController.java:538)
 +
                    at com.caucho.env.deploy.DeployContainer.update(DeployContainer.java:241)
 +
                    at com.caucho.env.deploy.DeployContainer.update(DeployContainer.java:223)
 +
                    at com.caucho.env.deploy.DeployContainer.add(DeployContainer.java:87)
 +
                    at com.caucho.server.webapp.WebAppContainer.addWebApp(WebAppContainer.java:413)
 +
                    at com.caucho.resin.ResinEmbed.deployWebApplication(ResinEmbed.java:581)
 +
                    at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:380)
 +
                    at com.caucho.resin.ResinLite.main(ResinLite.java:82)
 +
                   
 +
13-01-08 13:56:11.043 [http://*:8080-3] INFO WebApp - WebApp[production/webapp/default/ROOT] stopping
 +
13-01-08 13:56:15.778 [http://*:8080-3] WARNING JniTroubleshoot - Unable to find native library 'resin_os' for com.caucho.loader.ClassEntry. Resin expects to find this library in:
 +
                      (Unix) /home/pi/resin-lite/libexec/libresin_os.so
 +
                    On Unix, run ./configure --prefix=`pwd`; make; make install.
 +
                   
 +
                    The JVM exception was: java.lang.UnsatisfiedLinkError: Can't load library: /home/pi/resin-lite/webtest/libexec/libresin_os.so
 +
                   
 +
13-01-08 13:56:16.680 [http://*:8080-3] WARNING DynamicClassLoader - java.lang.NoClassDefFoundError: javax/faces/application/ViewHandlerWrapper
 +
                      while loading com.caucho.server.cdi.ConversationJsfViewHandler (in RootDynamicClassLoader[])
 +
13-01-08 13:56:17.119 [http://*:8080-3] INFO WebApp - WebApp[production/webapp/default/ROOT] active
 +
13-01-08 13:56:18.999 [http://*:8080-2] INFO TldManager - Loading .tld files from global classpath
 +
 
 +
=== Resin Lite on Cacao ===
 +
 
 +
Resin fails to startup on Cacao.  Log below...
 +
 
 +
pi@raspberrypi ~/resin-lite $ java -cacao -jar resin-lite.jar webtest.war
 +
ResinLite starting at Tue, 08 Jan 2013 14:06:02 -0500 (EST)
 +
LOG: [0x4007a000] jmm_GetMemoryManagers: FIX ME!
 +
LOG: [0x4007a000] jmm_GetMemoryPools: FIX ME!
 +
LOG: [0x4007a000] jmm_GetBoolAttribute: Unknown attribute 24
 +
LOG: [0x4007a000] jmm_GetBoolAttribute: Unknown attribute 25
 +
LOG: [0x4007a000] jmm_GetMemoryUsage: IMPLEMENT ME!
 +
java.lang.NullPointerException
 +
  at java.lang.Throwable.fillInStackTrace(Throwable.java:782)
 +
  at java.lang.Throwable.<init>(Throwable.java:250)
 +
  at java.lang.Exception.<init>(Exception.java:54)
 +
  at java.lang.RuntimeException.<init>(RuntimeException.java:51)
 +
  at java.lang.NullPointerException.<init>(NullPointerException.java:60)
 +
  at com.caucho.db.block.BlockManager.getMaxMemory(BlockManager.java:135)
 +
  at com.caucho.db.block.BlockManager.defaultCapacity(BlockManager.java:104)
 +
  at com.caucho.db.block.BlockManager.create(BlockManager.java:89)
 +
  at com.caucho.server.resin.ResinDelegate$BlockManagerMemoryFreeTask.<init>(ResinDelegate.java:396)
 +
  at com.caucho.server.resin.ResinDelegate.addPreTopologyServices(ResinDelegate.java:380)
 +
  at com.caucho.server.resin.Resin.preConfigureInit(Resin.java:760)
 +
  at com.caucho.server.resin.Resin.<init>(Resin.java:248)
 +
  at com.caucho.server.resin.ResinEmbedded.<init>(ResinEmbedded.java:46)
 +
  at com.caucho.server.resin.ResinEmbeddedLite.<init>(ResinEmbeddedLite.java:41)
 +
  at com.caucho.resin.ResinLite.createResin(ResinLite.java:109)
 +
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:335)
 +
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)
 +
Exception in thread "main" java.lang.UnsatisfiedLinkError: registerNatives
 +
  at java.lang.Throwable.fillInStackTrace(Throwable.java:782)
 +
  at java.lang.Throwable.<init>(Throwable.java:265)
 +
  at java.lang.Error.<init>(Error.java:70)
 +
  at java.lang.LinkageError.<init>(LinkageError.java:55)
 +
  at java.lang.UnsatisfiedLinkError.<init>(UnsatisfiedLinkError.java:54)
 +
  at java.lang.invoke.MethodHandleNatives.<clinit>(MethodHandleNatives.java:127)
 +
  at java.lang.invoke.MemberName.<init>(MemberName.java:352)
 +
  at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:960)
 +
  at com.caucho.config.attribute.SetterAttribute.<init>(SetterAttribute.java:55)
 +
  at com.caucho.config.type.InlineBeanType.addProp(InlineBeanType.java:892)
 +
  at com.caucho.config.type.InlineBeanType.introspectMethods(InlineBeanType.java:847)
 +
  at com.caucho.config.type.InlineBeanType.introspect(InlineBeanType.java:607)
 +
  at com.caucho.config.type.ConfigType.carefulIntrospect(ConfigType.java:68)
 +
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:593)
 +
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
 +
  at com.caucho.config.xml.XmlBeanAttribute.<init>(XmlBeanAttribute.java:57)
 +
  at com.caucho.config.xml.XmlBeanAttribute.<clinit>(XmlBeanAttribute.java:49)
 +
  at com.caucho.config.type.EnvironmentBeanType.<init>(EnvironmentBeanType.java:57)
 +
  at com.caucho.config.type.TypeFactory.createType(TypeFactory.java:626)
 +
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:586)
 +
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
 +
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:183)
 +
  at com.caucho.config.xml.XmlConfigContext.configure(XmlConfigContext.java:241)
 +
  at com.caucho.config.Config.configure(Config.java:324)
 +
  at com.caucho.config.Config.configure(Config.java:254)
 +
  at com.caucho.server.resin.BootConfig.configureFile(BootConfig.java:132)
 +
  at com.caucho.server.resin.Resin.configureFile(Resin.java:1023)
 +
  at com.caucho.resin.ResinEmbed.initConfig(ResinEmbed.java:520)
 +
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:344)
 +
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)
 +
 
 +
=== Resin on JamVm ===
 +
 
 +
Resin fails to startup on JamVM.  Log below:
 +
 
 +
pi@raspberrypi ~/resin-lite $ java -jamvm -jar resin-lite.jar webtest.war
 +
ResinLite starting at Tue, 08 Jan 2013 14:08:34 -0500 (EST)
 +
jmm_GetBoolAttribute: Unknown attribute 24
 +
jmm_GetBoolAttribute: Unknown attribute 25
 +
jmm_GetMemoryUsage
 +
java.lang.NullPointerException
 +
  at com.caucho.db.block.BlockManager.getMaxMemory(BlockManager.java:135)
 +
  at com.caucho.db.block.BlockManager.defaultCapacity(BlockManager.java:104)
 +
  at com.caucho.db.block.BlockManager.create(BlockManager.java:89)
 +
  at com.caucho.server.resin.ResinDelegate$BlockManagerMemoryFreeTask.<init>(ResinDelegate.java:396)
 +
  at com.caucho.server.resin.ResinDelegate.addPreTopologyServices(ResinDelegate.java:380)
 +
  at com.caucho.server.resin.Resin.preConfigureInit(Resin.java:760)
 +
  at com.caucho.server.resin.Resin.<init>(Resin.java:248)
 +
  at com.caucho.server.resin.ResinEmbedded.<init>(ResinEmbedded.java:46)
 +
  at com.caucho.server.resin.ResinEmbeddedLite.<init>(ResinEmbeddedLite.java:41)
 +
  at com.caucho.resin.ResinLite.createResin(ResinLite.java:109)
 +
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:335)
 +
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)
 +
Exception in thread "main" java.lang.UnsatisfiedLinkError: registerNatives
 +
  at java.lang.invoke.MethodHandleNatives.registerNatives(Native Method)
 +
  at java.lang.invoke.MethodHandleNatives.<clinit>(MethodHandleNatives.java:127)
 +
  at java.lang.invoke.MemberName.<init>(MemberName.java:352)
 +
  at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:960)
 +
  at com.caucho.config.attribute.SetterAttribute.<init>(SetterAttribute.java:55)
 +
  at com.caucho.config.type.InlineBeanType.addProp(InlineBeanType.java:892)
 +
  at com.caucho.config.type.InlineBeanType.introspectMethods(InlineBeanType.java:847)
 +
  at com.caucho.config.type.InlineBeanType.introspect(InlineBeanType.java:607)
 +
  at com.caucho.config.type.ConfigType.carefulIntrospect(ConfigType.java:68)
 +
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:593)
 +
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
 +
  at com.caucho.config.xml.XmlBeanAttribute.<init>(XmlBeanAttribute.java:57)
 +
  at com.caucho.config.xml.XmlBeanAttribute.<clinit>(XmlBeanAttribute.java:49)
 +
  at com.caucho.config.type.EnvironmentBeanType.<init>(EnvironmentBeanType.java:57)
 +
  at com.caucho.config.type.TypeFactory.createType(TypeFactory.java:626)
 +
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:586)
 +
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
 +
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:183)
 +
  at com.caucho.config.xml.XmlConfigContext.configure(XmlConfigContext.java:241)
 +
  at com.caucho.config.Config.configure(Config.java:324)
 +
  at com.caucho.config.Config.configure(Config.java:254)
 +
  at com.caucho.server.resin.BootConfig.configureFile(BootConfig.java:132)
 +
  at com.caucho.server.resin.Resin.configureFile(Resin.java:1023)
 +
  at com.caucho.resin.ResinEmbed.initConfig(ResinEmbed.java:520)
 +
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:344)
 +
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)
 +
 
 +
=== Resin Lite on Oracle JDK 7 ===
 +
 
 +
Resin starts up with warning and seems to run OK on Oracle JDK 7.  I can't use -server, but that was already established previously and not required anyway.
 +
 
 +
It's complaining about missing a JSF library, which it is since I did not include javax.faces jar.  Log below...
 +
 
 +
pi@raspberrypi ~/resin-lite $ /usr/jdk1.7.0_10/bin/java -jar resin-lite.jar webtest.war
 +
ResinLite starting at Tue, 08 Jan 2013 14:23:39 -0500 (EST)
 +
13-01-08 14:24:00.274 [main] INFO ResinSystem -
 +
13-01-08 14:24:00.283 [main] INFO ResinSystem - Resin-7.0.s130102 (built Wed, 02 Jan 2013 06:01:05 EST)
 +
13-01-08 14:24:00.288 [main] INFO ResinSystem -
 +
13-01-08 14:24:00.300 [main] INFO ResinSystem - Linux 3.2.27+ arm
 +
13-01-08 14:24:00.307 [main] INFO ResinSystem - Java(TM) SE Runtime Environment 1.7.0_10-b18, UTF-8, en
 +
13-01-08 14:24:00.319 [main] INFO ResinSystem - Java HotSpot(TM) Client VM 23.6-b04, 32, mixed mode, Oracle Corporation
 +
13-01-08 14:24:00.324 [main] INFO ResinSystem -
 +
13-01-08 14:24:00.330 [main] INFO ResinSystem - user.name  = pi
 +
13-01-08 14:24:01.998 [main] INFO Table - Table[mnode:2] validating indexes due to unclean shutdown.
 +
13-01-08 14:24:02.285 [main] INFO Table - Table[data:3] validating indexes due to unclean shutdown.
 +
13-01-08 14:24:02.668 [main] INFO ServletService -
 +
13-01-08 14:24:02.673 [main] INFO ServletService - resin.home = /home/pi/resin-lite
 +
13-01-08 14:24:02.679 [main] INFO ServletService - resin.root = /home/pi/resin-lite
 +
13-01-08 14:24:02.696 [main] INFO ServletService - resin.conf = /home/pi/resin-lite/conf/resin.conf
 +
13-01-08 14:24:02.702 [main] INFO ServletService -
 +
13-01-08 14:24:02.727 [main] INFO ServletService - server    = 127.0.0.1:-1 (:default)
 +
13-01-08 14:24:02.734 [main] INFO ServletService - stage      = production
 +
13-01-08 14:24:05.028 [main] INFO Host - Host[production/host/default] active
 +
13-01-08 14:24:05.042 [main] INFO ServletService - ServletService[id=default,cluster=] active
 +
13-01-08 14:24:05.064 [main] INFO NetworkListenSystem -
 +
13-01-08 14:24:05.169 [main] INFO TcpPort - http listening to *:8080
 +
13-01-08 14:24:06.096 [main] INFO NetworkListenSystem -
 +
13-01-08 14:24:06.139 [main] INFO Resin - ResinEmbeddedLite[id=default] started in 21030ms
 +
13-01-08 14:24:10.427 [main] WARNING JniTroubleshoot - Unable to find native library 'resin_os' for com.caucho.loader.ClassEntry. Resin expects to find this library in:
 +
                      (Unix) /home/pi/resin-lite/libexec/libresin_os.so
 +
                    On Unix, run ./configure --prefix=`pwd`; make; make install.
 +
                   
 +
                    The JVM exception was: java.lang.UnsatisfiedLinkError: Can't load library: /home/pi/resin-lite/webtest/libexec/libresin_os.so
 +
                   
 +
13-01-08 14:24:11.904 [main] WARNING DynamicClassLoader - java.lang.NoClassDefFoundError: javax/faces/application/ViewHandlerWrapper
 +
                      while loading com.caucho.server.cdi.ConversationJsfViewHandler (in RootDynamicClassLoader[])
 +
13-01-08 14:24:12.217 [main] INFO WebApp - WebApp[production/webapp/default/ROOT] active
 +
13-01-08 14:27:18.415 [http://*:8080-4] INFO TldManager - Loading .tld files from global classpath
 +
 
 +
= Wireless =
 +
 
 +
I purchased this [http://adafruit.com/products/814 cute little USB Wifi adapter from Adafruit] for only $12.  What a pain to setup if you don't use outdated WEP or WPA wireless networking.  I use WPA2 with AES/CCMP (like everyone really really should be).  Here's my config that finally worked using Raspbian Wheezy 2012-12-16 (not Occidentalis).  (At the time of writing this, Occidentalis is a few releases behind Raspbian.  Plus I was getting very weird keyboard ghosting using Occidentalis.  Not sure why but it doesn't happen with Rasbian.)
 +
 
 +
I did NOT have to install any drivers.
 +
 
 +
pi@raspberrypi ~ $ cat /etc/network/interfaces
 +
auto lo
 +
 +
iface lo inet loopback
 +
iface eth0 inet dhcp
 +
 +
allow-hotplug wlan0
 +
iface wlan0 inet manual
 +
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
 +
iface default inet dhcp
 +
 
 +
pi@raspberrypi ~ $ sudo cat /etc/wpa_supplicant/wpa_supplicant.conf
 +
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
 +
update_config=1
 +
 +
network={
 +
ssid="your_sid"
 +
#psk="wireless password"
 +
psk=generated_by_wpa_passphrase
 +
proto=RSN
 +
key_mgmt=WPA-PSK
 +
pairwise=CCMP
 +
auth_alg=OPEN
 +
}
  
 +
I found you can put your wireless password in for "psk", but I don't like having passwords in clear text.  So run "wpa_passphrase <sid> <password>" it generates a psk you can use instead
  
 +
wpa_supplicant reference: [http://www.lsi.upc.edu/lclsi/Manuales/wireless/files/wpa_supplicant.conf]
  
I started with this article
+
pi@raspberrypi ~ $ sudo ifconfig -a
http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html
+
eth0      Link encap:Ethernet  HWaddr b8:27:eb:c7:9c:8a 
 +
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
 +
          RX packets:10621 errors:0 dropped:0 overruns:0 frame:0
 +
          TX packets:3979 errors:0 dropped:0 overruns:0 carrier:0
 +
          collisions:0 txqueuelen:1000
 +
          RX bytes:4256838 (4.0 MiB)  TX bytes:533647 (521.1 KiB)
 +
 +
lo        Link encap:Local Loopback 
 +
          inet addr:127.0.0.1  Mask:255.0.0.0
 +
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
 +
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
 +
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
 +
          collisions:0 txqueuelen:0
 +
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
 +
 +
wlan0    Link encap:Ethernet  HWaddr 00:e0:4c:10:47:f2 
 +
          inet addr:192.168.1.16  Bcast:192.168.1.255  Mask:255.255.255.0
 +
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
 +
          RX packets:4761 errors:0 dropped:7099 overruns:0 frame:0
 +
          TX packets:237 errors:0 dropped:0 overruns:0 carrier:0
 +
          collisions:0 txqueuelen:1000
 +
          RX bytes:915418 (893.9 KiB)  TX bytes:39607 (38.6 KiB)
  
 +
= sddd =
  
 +
I've written a nice little script for OSX to help in imaging an SD card.  See [[sddd| sdd - Paul's dd for SD Card script for OSX]]
  
 
</font>
 
</font>

Latest revision as of 00:00, 8 February 2013

Embed-48.pngPie48.png

Contents

Intro

Hi! I'm Paul Cowan, a software engineer at Caucho Technology. Caucho is primarily a Java EE application server vendor. Our application server is called Resin. I mostly write Java code, but I'm also a computer hobbyist and like to tinker with anything techie.

During Caucho's last engineer meeting in San Francisco (October 2012), I brought up Raspberry Pi as an avenue we could explore for Resin. It probably wouldn't directly sell Resin licenses, but it would be a great marketing vehicle. Everybody liked it, Caucho is cool like that, and so I'm off.

About Resin

Resin is a fairly light-weight for an app server and embeds well. It's really a nice platform on which to build just about anything in Java, since it can make just about any app HTTP enabled and handles all the mundane services like logging and you don't really want to have to deal with. It also provides a dependency injection container... Now you may be asking "why do I can about dependency injection when I'm just playing around with hobby projects." Well personally I pump out Java code much faster using dependency injection and just find it easier to write in that style.

Resin also includes Quercus, a Java based PHP interpreter. I'm not really planning to make PHP a focus of this project, but it's handy to have available just in case.

About This Journal

The Raspberry Pi platform and community certainly seems to be evolving rapidly, but it still seems like there's not enough documentation out there. In particular Java support is kinda spotty, and I haven't found anything on JEE on a Raspberry Pi. So I'm going to document my experience in hope it is useful to other Java developers getting started with Raspberry Pi.

Hardware

I ordered the Pi early in October, but it was backordered by about 4 weeks. 10/15 they sent me an email my order was upgraded for free from 256 Mb to the 512 Mb model. It was delivered 10/18, so about 2 weeks early.

I use an IOGear DVI KVM so monitor and keyboard aren't a problem. In fact the KVM combines the mouse and keyboard into a single USB cable, so that leaves me a free USB port on the RasPi. However I needed an adapter and HDMI cable. Monoprice is great for this kind of stuff.

  • PNY 8 Gb SD card from BJ's... I think, I stolen from the family camera :)
  • MicroUSB cable and AC adapter from my Kindle


Raspi-1.gif Raspi-2.gif Raspi-3.gif Raspi-4.gif

Getting Started

I started with this write up from Oracle and the Raspberry Pi downloads page. It becomes apparent pretty quickly that there's a float-point compatibility issue with Java on Raspberry Pi. Here's a summary of what I understand regarding the state of Raspberry Pi operating systems and Java support as of 11/2012:

OS

  • The "official" distro is Raspbian Wheezy, which is offered for download on on raspberrypi.org/downloads
  • This distro is variant of Raspbian Wheezy from raspbian.org but with a light-weight desktop, Midori web browser, and a few other development extra specifically for Raspberry Pi
  • Raspbian Wheezy is a variant of Debian Wheezy but compiled for ARM processor with optimization specifically for Raspberry Pi (hardware floating-point)
  • Debian Wheezy is the "testing" distro of Debian, while Debian Squeeze is the current stable release
  • There are various other linux distros supporting ARM processor

I should mention that my understand is you can't just use any ARM linux distro straight up. The boot sequence for a Raspberry Pi dependent on the SD card. It actually boots from a small RISC core on the GPU, but the GPU firmware is loaded from the SD card. More here.

This article helps if you're a little lost like I was: Understanding ARM Architectures.

Java Compatability

  • Currently NO Java distro that I'm aware of has support for Raspberry Pi's hardware floating point unit (hard-float)
  • Therefore we need OS distro that support soft-float, ARMv6, little-endian
  • The Oracle article is discussing using Debian Squeeze, which I suspect is because it was the best distro available at the time with soft floating-point support.
  • However there is now a Soft-float Debian wheezy Rasbian image available at raspberrypi.org/downloads, so I'm going to try that to start out

Honestly I don't want a desktop at all and would like fast boot, so the Arch Linux distro appeals to me. (Note to try it later.)

Imaging

There's a Fedora installer that sounds interesting, but I'm running on OSX. The instructions on the Oracle article are based on Linux, but there's also decent instructions here. Basically the distro is a raw SD card image, containing partitions, so you have to write it directly to the SD card in raw form.

  • Inserted the SD card into my MacBook's SD Slot
  • Ran Search->Disk Utility
  • SD card is listed as 8.01 GB APPLE SD Card...
  • Erase->MS-DOS(FAT), Name: RASPI
  • Erase

Next, I tried RasPiWrite and failed. The script doesn't even run due to syntax errors. I'm not going to debug a Python script, so that fails the 10-minute test.

Now following "Easy Way" instructions from the Raspberry Pi wiki...

  • df -h reveals my SD card mount simply enough:
/dev/disk1s1   7.4Gi  624Ki  7.4Gi     1%    /Volumes/RASPI
$ sudo diskutil unmount /dev/disk1s1
Password:
Volume RASPI on disk1s1 unmounted
$ sudo dd bs=1m if=~/Downloads/2012-08-08-wheezy-armel.img of=/dev/rdisk1
1850+0 records in
1850+0 records out
1939865600 bytes transferred in 136.071302 secs (14256243 bytes/sec)

Well that looks like it worked!

Raspi-5.png

First Boot

The Raspberry Pi booted right into a blue menu screen called raspi-config that lets you configure basic OS settings.

  • The first thing I did was hit EXPAND-ROOTFS to use of the rest of the free space on the SD card
  • After a "sudo reboot" it printed logs about resizing the root file system. That took a few minutes but seems work fine.
  • I configured, locale, timezone, enabled SSHD, and set the the desktop to NOT start on boot
  • Finished, reboot
  • The pi is showing up on my network, SSH works, looks good to go!
pi@raspberrypi ~ $ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          7.3G  1.3G  5.7G  19% /
/dev/root       7.3G  1.3G  5.7G  19% /
tmpfs            22M  228K   22M   2% /run
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs            44M     0   44M   0% /tmp
tmpfs            10M     0   10M   0% /dev
tmpfs            44M     0   44M   0% /run/shm
/dev/mmcblk0p1   56M   35M   22M  61% /boot

The Oracle article goes into a lot of detail about setting up DHCP, local. time-zone, etc e which doesn't seem necessary since Raspbian provides raspi-config.

Hmm, I'm noticing the OS is only seeing 256 Mb instead of 512.... They told me I was sent an upgraded model to the 512 Mb.

pi@raspberrypi ~ $ free -h
            total       used       free     shared    buffers     cached
Mem:          216M        48M       168M         0B       9.0M        23M
-/+ buffers/cache:        15M       200M
Swap:          99M         0B        99M
pi@raspberrypi ~ $ cat /proc/cpuinfo 
Processor	: ARMv6-compatible processor rev 7 (v6l)
BogoMIPS	: 697.95
Features	: swp half thumb fastmult vfp edsp java tls 
CPU implementer	: 0x41
CPU architecture: 7
CPU variant	: 0x0
CPU part	: 0xb76
CPU revision	: 7
 
Hardware	: BCM2708
Revision	: 0005
Serial		: 00000000edc79c8a

(Emailed Newark customer service about it, have not heard back yet).

Getting Oracle JRE 7 Running

As I mentioned above, there's no Raspi hardware floating-point support in Java (yet?). I'm planning to install Oracle/OpenJDK/JRE to do some testing and see what runs best. Resin is not fully functional with a JRE, it can't compile JSPs...

Downloading ARMv6/7 Linux - Headless EABI, VFP, SoftFP ABI, Little Endian1 (ejre-7u6-fcs-b24-linux-arm-vfp-client_headless-10_aug_2012.tar.gz) from Oracle.

(Hmm, it takes like 2 minutes to scp 32Mb to the Pi from OSX... That troubling. Not sure if it's the write to SD card speed or network.)

Unziped, untar, there's no installer. There's only 2 files in bin, java and keytool. I'm going to setup Java like a typical linux install by moving the extracted dir to /usr/ejre1.7.0_06 and symlink to /usr/java and link the executables into /usr/bin.

pi@raspberrypi ~ $ which java
/usr/bin/java
pi@raspberrypi ~ $ java -version
java version "1.7.0_06"
Java(TM) SE Embedded Runtime Environment (build 1.7.0_06-b24, headless)
Java HotSpot(TM) Embedded Client VM (build 23.2-b09, mixed mode)

Getting Resin Running

I'm going to focus on the open-source Resin Servlet Container for this project.

wget http://www.caucho.com/download/resin-4.0.32.zip

Extracting the zip was fast, but the whole system then stopped responding for a few seconds afterwards... I guessing it's write buffering to the SD card and has to wait for the hardware to catchup. (?)

Trying a configure/make/make install of Resin:

./configure

configure: error: 

   *** Can't find JNI directory in JAVA_HOME=/usr/java
   *** JNI is expected in /usr/java/include/linux
 

Crap... this Java distro does not include the Java headers. We won't be able to compile Resin native libraries with this Java, maybe one of the others will have headers. Resin will still work in pure Java mode.

Let's try with:

./configure --disable-jni

Configure succeeds that time. "make" succeeds. "sudo make install" succeeds.

Resin is installed to /etc/init.d, /etc/resin, /usr/local/share/resin, /var/resin, etc.

pi@raspberrypi /var/resin $ resinctl start
Resin/4.0.32 launching watchdog at 127.0.0.1:6600
java.io.FileNotFjava.io.FiloundExceNotFoeption:undExce /var/ption: /log/resivar/logn/watch/resin/dog-manwatchdoager.log g-manage(Permissr.log (Pion deermissionied)
n denied)
	at java.io.FileOutputStream.open(Native Method)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
	at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
	at com.caucho.vfs.FilePath.openAppendImpl(FilePath.java:586)
	at com.caucho.vfs.Path.openAppend(Path.java:1229)
	at com.caucho.boot.WatchdogManager.<init>(WatchdogManager.java:143)
	at com.caucho.boot.WatchdogManager.main(WatchdogManager.java:1009)
Resin/4.0.32 started -server 'app-0' with watchdog at 127.0.0.1:6600

Well that's a weird error... I forgot to start with sudo, retry.

pi@raspberrypi /var/log/resin $ sudo resinctl start
Resin/4.0.32 launching watchdog at 127.0.0.1:6600
Resin/4.0.32 started -server 'app-0' with watchdog at 127.0.0.1:6600

That's better. It only took about 15 seconds to startup, not too bad. Checking the logs...

[2012/12/04 14:14:31.094] {main} Unable to find native library 'resin_os' for com.caucho.bootjni.JniProcess. Resin expects to find this library in:
                                  (Unix) /usr/local/share/resin-4.0.32/libexec/libresin_os.so
                                On Unix, run ./configure --prefix=`pwd`; make; make install.
                                
                                The JVM exception was: java.lang.UnsatisfiedLinkError: no resin_os in java.library.path

watchdog-manager.log is complaining about missing native libraries, but that's expected.

[12-12-04 14:15:12.478] {main} Resin-4.0.32 (built Mon, 01 Oct 2012 03:05:04 PDT)
[12-12-04 14:15:12.482] {main} 
[12-12-04 14:15:12.485] {main} Linux 3.2.27+ arm
[12-12-04 14:15:12.489] {main} Java(TM) SE Embedded Runtime Environment 1.7.0_06-b24, UTF-8, en
[12-12-04 14:15:12.493] {main} Java HotSpot(TM) Embedded Client VM 23.2-b09, 32, mixed mode, Oracle Corporation

Cool!

Trying http://raspberrypi:8080/

500 Servlet Exception

javac compiler is not available in Java(TM) SE Embedded Runtime Environment
1.7.0_06-b24. Check that you are using the JDK, not the JRE.

Well that's expect also, we're using a JRE so no JSP compiler...

Trying http://raspberrypi:8080/resin-doc/ That works! Why?... XTP is not compiled!

Trying http://raspberrypi:8080/resin-admin That works too! PHP is not compiled either!

Admin account generation worked. Resin restart took 45 seconds, Ugh.

Raspi-6.png

Getting OpenJDK 7 Running

Attempting to install OpenJDK from the package:

apt-get install openjdk-7-jdk

Nice! That works!

root@raspberrypi:~# which java
/usr/bin/java
root@raspberrypi:~# cd /usr/bin/
root@raspberrypi:/usr/bin# ls -l java
lrwxrwxrwx 1 root root 22 Dec  4 16:21 java -> /etc/alternatives/java
root@raspberrypi:/usr/bin# cd /etc/alternatives/
root@raspberrypi:/etc/alternatives# ls -l java
lrwxrwxrwx 1 root root 46 Dec  4 16:21 java -> /usr/lib/jvm/java-7-openjdk-armel/jre/bin/java
root@raspberrypi:/etc/alternatives# cd /usr/lib/jvm/
root@raspberrypi:/usr/lib/jvm# ls -l
total 8
lrwxrwxrwx 1 root root   20 Oct 18 03:13 java-1.7.0-openjdk-armel -> java-7-openjdk-armel
drwxr-xr-x 7 root root 4096 Dec  4 16:19 java-7-openjdk-armel
drwxr-xr-x 3 root root 4096 Dec  4 16:16 java-7-openjdk-common

So OpenJDK uses the Linux Alternatives project... (Not a big fan of alternatives but I'll deal.) It install armel and common, not sure what that's about.

Starting Resin with OpenJDK...

[12-12-05 20:05:52.793] {main} 
[12-12-05 20:05:52.817] {main} Resin-4.0.32 (built Mon, 01 Oct 2012 03:05:04 PDT)
[12-12-05 20:05:52.826] {main} 
[12-12-05 20:05:52.838] {main} Linux 3.2.27+ arm
[12-12-05 20:05:52.872] {main} OpenJDK Runtime Environment 1.7.0_03-b21, UTF-8, en
[12-12-05 20:05:52.887] {main} OpenJDK Zero VM 22.0-b10, 32, mixed mode, Oracle Corporation

Ok it start, but wow it's really slow. ResinBoot itself took like 20 seconds, and it must have been 3 minutes before port 8080 was bound. http://raspberrypi:8080/ loads to, but it took like 40 seconds.

Doing some research, I see there's 3 different VM's built into OpenJDK, that's interesting. Here's the 3:


The /usr/lib/jvm/java-7-openjdk-armel/docs/README.Debian explains this in detail:

The OpenJDK build is configured --with-additional-vms to build with
different virtual machines.  The original implementation of the hotspot
VM is only available on the amd64, i386, lpia and sparc architectures.
Other VM's are CACAO, providing a just in time compiler on several
architectures (although the VM implementation is incomplete), and Zero,
providing a byte code interpreter for every architecture.  On some
architectures Zero is built with JIT support using shark (still considered
experimental).

To use a different VM other than the default, use

       java -cacao|-zero|-shark

or for the java tools, use

        <tool name> -J-cacao|-J-zero|-J-shark.

The zero build on the ix86 architectures is built with shark (just in time
compiler); to use the zero build without shark support, use the `-Xint'
option to operate in interpreted-only mode.

On some architectures (currently armel and powerpc, when built against
llvm-2.6) which use ther zero vm as the default, the openjdk-7-jre-zero
package contains the shark vm.
 
To change the default permanently, edit /etc/java-7-openjdk/jvm.cfg.

The CACAO VM can be found in the icedtea-7-jre-cacao package, the Zero/Shark
VM can be found in the openjdk-7-jre-zero package (on the architectures
where the Hotspot VM is available).

So Zero is the default, which is interpreted mode, so that could account for the slow performance I was seeing. Sounds like I need to do some performance testing.

I see OpenJDK includes headers!

root@raspberrypi:/usr/lib/jvm/java-7-openjdk-armel/include# ls -l
total 212
-rw-r--r-- 1 root root 21079 Oct 18 03:05 classfile_constants.h
-rw-r--r-- 1 root root  9544 Oct 18 03:05 jawt.h
lrwxrwxrwx 1 root root    15 Oct 18 03:13 jawt_md.h -> linux/jawt_md.h
-rw-r--r-- 1 root root  7206 Oct 18 03:05 jdwpTransport.h
-rw-r--r-- 1 root root 74663 Oct 18 03:05 jni.h
lrwxrwxrwx 1 root root    14 Oct 18 03:13 jni_md.h -> linux/jni_md.h
-rw-r--r-- 1 root root  4771 Oct 18 03:05 jvmticmlr.h
-rw-r--r-- 1 root root 78425 Oct 18 03:05 jvmti.h
drwxr-xr-x 2 root root  4096 Dec  4 16:19 linux

So I wonder if Resin will compile on Raspberry Pi now... Trying...

./configure works!

Resin Configuration Summary:

 RESIN       : 4.0.32
   home      : /usr/local/share/resin-4.0.32
   root      : /var/resin
   conf      : /etc/resin
   log       : /var/log/resin
   plugins   : common resin_os 
   init      : /etc/init.d/resin

 JAVA_HOME   : /usr/lib/jvm/java-7-openjdk-armel/jre/bin/../..

 JNI         : 32-bit
   include       : -I/usr/lib/jvm/java-7-openjdk-armel/jre/bin/../../include
   CFLAGS        : 
   cflags_shlib  : -fpic
   ld_shlib      : gcc
   ldflags_shlib : -shared -fPIC -m32
   libs_shlib    : 
   epoll() for keepalives

But make fails:

gcc -g -O2 -DEPOLL -D_POSIX_PTHREAD_SEMANTICS -pthread -fPIC -fno-omit-frame-pointer -O2 -DHAS_SOCK_TIMEOUT -DHAS_SENDFILE -DHAS_SPLICE -DPOLL -DHAS_JVMTI  -fPIC -m32 -DRESIN_HOME=\"/usr/local/share/resin-4.0.32\" -I/usr/include -I/usr/lib/jvm/java-7-openjdk-armel/jre/bin/../../include  -I../common -DCPU=\"armv6l\" -DOS=   -c -o boot.o boot.c
cc1: error: unrecognized command line option �-m32�

So gcc on Raspberry Pi doesn't like -m32... It's a 32-bit architecture. I can probably work out the proper compilation flags but will put that off until later. For now we'll continue to run Resin in java-only mode.

JVM Performance Testing

Resin on OpenJDK

Resin is automatically adding -server to the Resin command line during startup. -server implies -zero, so I can't get it to use -cacao or -jamvm at all without changes.

I'm staring a Resin Changes To Support Raspberry Pi list.

Oracle JDK on Raspberry Pi

I'm quite interested in trying Pi4J, which looks like a great little Java wrapper around a native library called WiringPi that lets you work with the Raspi hardware directly (GPIO, serial port, etc)

The maintainer of Pi4J has a decent write on Raspberry Pi - Installing Oracle Java Development Kit (JDK 1.7.0u6). So reading that I come to find out there IS an Oracle JDK that works on Raspberry Pi! (WTF Oracle? Why isn't this listed under "Java Embedded". I guess because the "embedded" version is stripped down to make the size smaller.) Anyway, visit the Oracle downloads page, Java SE 7u10, JDK, there's a version available for "Linux ARM v6/v7 Soft Float ABI". That's what we need... Now to redo my Java On Raspberry Pi Performance tests, again.

Resin on Oracle JDK

Unfortunately I've hit a wall with Resin in it's current state. Resin automatically adds "-server" to the server startup command, and the JDK apparently won't run on Raspberry Pi with -server. It complains about requiring and ARMv7 chip, but the Pi is v6... (Resin embed may work.)

pi@raspberrypi ~/resin-4.0.32 $ /usr/java/bin/java -jar lib/resin.jar start 
Resin/4.0.32 launching watchdog at 127.0.0.1:6600
Error occurred during initialization of VM 
Server VM is only supported on ARMv7+ VFP

Adding "remove -server" to the Resin Changes To Support Raspberry Pi list, and starting work on the changes to Resin 7.

Resin Lite

I'm coming back to this after a few weeks of holidays, distractions, bug fixes, and various other work... I've created a special cut of our next version of Resin, Resin 7, called "Resin Lite". Resin Lite is a single jar .war runner. To be honest it's no very "lite" yet, but at least it should run better on RasPi since it won't add -server automatically.

Resin Lite on Zero

Resin starts on Zero with exceptions but appears to run OK. I get a response to a servlet. Performance is slow. Log below...

pi@raspberrypi ~/resin-lite $ java -zero -jar resin-lite.jar webtest.war 
ResinLite starting at Tue, 08 Jan 2013 13:53:11 -0500 (EST)
13-01-08 13:54:44.881 [main] INFO ResinSystem - 
13-01-08 13:54:44.890 [main] INFO ResinSystem - Resin-7.0.s130102 (built Wed, 02 Jan 2013 06:01:05 EST)
13-01-08 13:54:44.896 [main] INFO ResinSystem - 
13-01-08 13:54:44.903 [main] INFO ResinSystem - Linux 3.2.27+ arm
13-01-08 13:54:44.909 [main] INFO ResinSystem - OpenJDK Runtime Environment 1.7.0_03-b21, UTF-8, en
13-01-08 13:54:44.916 [main] INFO ResinSystem - OpenJDK Zero VM 22.0-b10, 32, mixed mode, Oracle Corporation
13-01-08 13:54:44.922 [main] INFO ResinSystem - 
13-01-08 13:54:44.931 [main] INFO ResinSystem - user.name  = pi
13-01-08 13:54:47.206 [main] INFO ServletService - 
13-01-08 13:54:47.213 [main] INFO ServletService - resin.home = /home/pi/resin-lite
13-01-08 13:54:47.219 [main] INFO ServletService - resin.root = /home/pi/resin-lite
13-01-08 13:54:47.232 [main] INFO ServletService - resin.conf = /home/pi/resin-lite/conf/resin.conf
13-01-08 13:54:47.236 [main] INFO ServletService - 
13-01-08 13:54:47.243 [main] INFO ServletService - server    = 127.0.0.1:-1 (:default)
13-01-08 13:54:47.249 [main] INFO ServletService - stage      = production
13-01-08 13:54:49.206 [main] INFO Host - Host[production/host/default] active
13-01-08 13:54:49.225 [main] INFO ServletService - ServletService[id=default,cluster=] active
13-01-08 13:54:49.257 [main] INFO NetworkListenSystem - 
13-01-08 13:54:49.397 [main] INFO TcpPort - http listening to *:8080
13-01-08 13:54:50.740 [main] INFO NetworkListenSystem - 
13-01-08 13:54:50.785 [main] INFO Resin - ResinEmbeddedLite[id=default] started in 25338ms
13-01-08 13:55:30.871 [main] WARNING WebApp - java.lang.InternalError: NYI
                    	at java.lang.invoke.AdapterMethodHandle.makeReturnConversion(AdapterMethodHandle.java:252)
                    	at java.lang.invoke.AdapterMethodHandle.makePairwiseConvert(AdapterMethodHandle.java:208)
                    	at java.lang.invoke.MethodHandleImpl.convertArguments(MethodHandleImpl.java:760)
                    	at java.lang.invoke.MethodHandleImpl.collectArguments(MethodHandleImpl.java:842)
                    	at java.lang.invoke.MethodHandleImpl.collectArguments(MethodHandleImpl.java:820)
                    	at java.lang.invoke.MethodHandle.asCollector(MethodHandle.java:889)
                    	at java.lang.invoke.AdapterMethodHandle$AsVarargsCollector.<init>(AdapterMethodHandle.java:568)
                    	at java.lang.invoke.AdapterMethodHandle.makeVarargsCollector(AdapterMethodHandle.java:556)
                    	at java.lang.invoke.MethodHandleImpl.findMethod(MethodHandleImpl.java:95)
                    	at java.lang.invoke.MethodHandles$Lookup.accessStatic(MethodHandles.java:592)
                    	at java.lang.invoke.MethodHandles$Lookup.findStatic(MethodHandles.java:587)
                    	at sun.invoke.util.ValueConversions$LazyStatics.<clinit>(ValueConversions.java:694)
                    	at sun.invoke.util.ValueConversions.buildArrayProducer(ValueConversions.java:1176)
                    	at sun.invoke.util.ValueConversions.varargsArray(ValueConversions.java:1164)
                    	at java.lang.invoke.MethodHandle.asCollector(MethodHandle.java:888)
                    	at java.lang.invoke.AdapterMethodHandle$AsVarargsCollector.<init>(AdapterMethodHandle.java:568)
                    	at java.lang.invoke.AdapterMethodHandle.makeVarargsCollector(AdapterMethodHandle.java:556)
                    	at java.lang.invoke.MethodHandleImpl.findMethod(MethodHandleImpl.java:95)
                    	at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:963)
                    	at com.caucho.config.attribute.SetterAttribute.<init>(SetterAttribute.java:55)
                    	at com.caucho.config.type.InlineBeanType.addProp(InlineBeanType.java:892)
                    	at com.caucho.config.type.InlineBeanType.introspectMethods(InlineBeanType.java:847)
                    	at com.caucho.config.type.InlineBeanType.introspect(InlineBeanType.java:607)
                    	at com.caucho.config.type.ConfigType.carefulIntrospect(ConfigType.java:68)
                    	at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:593)
                    	at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
                    	at com.caucho.config.attribute.CreateAttribute.getConfigType(CreateAttribute.java:75)
                    	at com.caucho.config.attribute.Attribute.isProgram(Attribute.java:74)
                    	at com.caucho.config.xml.XmlConfigContext.configureChildNode(XmlConfigContext.java:452)
                    	at com.caucho.config.xml.XmlConfigContext.configureAttribute(XmlConfigContext.java:324)
                    	at com.caucho.config.program.NodeBuilderChildProgram.inject(NodeBuilderChildProgram.java:82)
                    	at com.caucho.config.program.ContainerProgram.inject(ContainerProgram.java:88)
                    	at com.caucho.config.program.ConfigProgram.configure(ConfigProgram.java:107)
                    	at com.caucho.env.deploy.EnvironmentDeployController.configureInstance(EnvironmentDeployController.java:480)
                    	at com.caucho.env.deploy.EnvironmentDeployController.configureInstance(EnvironmentDeployController.java:59)
                    	at com.caucho.env.deploy.DeployController.startImpl(DeployController.java:684)
                    	at com.caucho.env.deploy.StartAutoRedeployAutoStrategy.startOnInit(StartAutoRedeployAutoStrategy.java:77)
                    	at com.caucho.env.deploy.DeployController.startOnInit(DeployController.java:538)
                    	at com.caucho.env.deploy.DeployContainer.update(DeployContainer.java:241)
                    	at com.caucho.env.deploy.DeployContainer.update(DeployContainer.java:223)
                    	at com.caucho.env.deploy.DeployContainer.add(DeployContainer.java:87)
                    	at com.caucho.server.webapp.WebAppContainer.addWebApp(WebAppContainer.java:413)
                    	at com.caucho.resin.ResinEmbed.deployWebApplication(ResinEmbed.java:581)
                    	at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:380)
                    	at com.caucho.resin.ResinLite.main(ResinLite.java:82)
                    
13-01-08 13:56:11.043 [1] INFO WebApp - WebApp[production/webapp/default/ROOT] stopping
13-01-08 13:56:15.778 [2] WARNING JniTroubleshoot - Unable to find native library 'resin_os' for com.caucho.loader.ClassEntry. Resin expects to find this library in:
                      (Unix) /home/pi/resin-lite/libexec/libresin_os.so
                    On Unix, run ./configure --prefix=`pwd`; make; make install.
                    
                    The JVM exception was: java.lang.UnsatisfiedLinkError: Can't load library: /home/pi/resin-lite/webtest/libexec/libresin_os.so
                    
13-01-08 13:56:16.680 [3] WARNING DynamicClassLoader - java.lang.NoClassDefFoundError: javax/faces/application/ViewHandlerWrapper
                      while loading com.caucho.server.cdi.ConversationJsfViewHandler (in RootDynamicClassLoader[])
13-01-08 13:56:17.119 [4] INFO WebApp - WebApp[production/webapp/default/ROOT] active
13-01-08 13:56:18.999 [5] INFO TldManager - Loading .tld files from global classpath

Resin Lite on Cacao

Resin fails to startup on Cacao. Log below...

pi@raspberrypi ~/resin-lite $ java -cacao -jar resin-lite.jar webtest.war 
ResinLite starting at Tue, 08 Jan 2013 14:06:02 -0500 (EST)
LOG: [0x4007a000] jmm_GetMemoryManagers: FIX ME!
LOG: [0x4007a000] jmm_GetMemoryPools: FIX ME!
LOG: [0x4007a000] jmm_GetBoolAttribute: Unknown attribute 24
LOG: [0x4007a000] jmm_GetBoolAttribute: Unknown attribute 25
LOG: [0x4007a000] jmm_GetMemoryUsage: IMPLEMENT ME!
java.lang.NullPointerException
  at java.lang.Throwable.fillInStackTrace(Throwable.java:782)
  at java.lang.Throwable.<init>(Throwable.java:250)
  at java.lang.Exception.<init>(Exception.java:54)
  at java.lang.RuntimeException.<init>(RuntimeException.java:51)
  at java.lang.NullPointerException.<init>(NullPointerException.java:60)
  at com.caucho.db.block.BlockManager.getMaxMemory(BlockManager.java:135)
  at com.caucho.db.block.BlockManager.defaultCapacity(BlockManager.java:104)
  at com.caucho.db.block.BlockManager.create(BlockManager.java:89)
  at com.caucho.server.resin.ResinDelegate$BlockManagerMemoryFreeTask.<init>(ResinDelegate.java:396)
  at com.caucho.server.resin.ResinDelegate.addPreTopologyServices(ResinDelegate.java:380)
  at com.caucho.server.resin.Resin.preConfigureInit(Resin.java:760)
  at com.caucho.server.resin.Resin.<init>(Resin.java:248)
  at com.caucho.server.resin.ResinEmbedded.<init>(ResinEmbedded.java:46)
  at com.caucho.server.resin.ResinEmbeddedLite.<init>(ResinEmbeddedLite.java:41)
  at com.caucho.resin.ResinLite.createResin(ResinLite.java:109)
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:335)
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)
Exception in thread "main" java.lang.UnsatisfiedLinkError: registerNatives
  at java.lang.Throwable.fillInStackTrace(Throwable.java:782)
  at java.lang.Throwable.<init>(Throwable.java:265)
  at java.lang.Error.<init>(Error.java:70)
  at java.lang.LinkageError.<init>(LinkageError.java:55)
  at java.lang.UnsatisfiedLinkError.<init>(UnsatisfiedLinkError.java:54)
  at java.lang.invoke.MethodHandleNatives.<clinit>(MethodHandleNatives.java:127)
  at java.lang.invoke.MemberName.<init>(MemberName.java:352)
  at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:960)
  at com.caucho.config.attribute.SetterAttribute.<init>(SetterAttribute.java:55)
  at com.caucho.config.type.InlineBeanType.addProp(InlineBeanType.java:892)
  at com.caucho.config.type.InlineBeanType.introspectMethods(InlineBeanType.java:847)
  at com.caucho.config.type.InlineBeanType.introspect(InlineBeanType.java:607)
  at com.caucho.config.type.ConfigType.carefulIntrospect(ConfigType.java:68)
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:593)
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
  at com.caucho.config.xml.XmlBeanAttribute.<init>(XmlBeanAttribute.java:57)
  at com.caucho.config.xml.XmlBeanAttribute.<clinit>(XmlBeanAttribute.java:49)
  at com.caucho.config.type.EnvironmentBeanType.<init>(EnvironmentBeanType.java:57)
  at com.caucho.config.type.TypeFactory.createType(TypeFactory.java:626)
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:586)
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:183)
  at com.caucho.config.xml.XmlConfigContext.configure(XmlConfigContext.java:241)
  at com.caucho.config.Config.configure(Config.java:324)
  at com.caucho.config.Config.configure(Config.java:254)
  at com.caucho.server.resin.BootConfig.configureFile(BootConfig.java:132)
  at com.caucho.server.resin.Resin.configureFile(Resin.java:1023)
  at com.caucho.resin.ResinEmbed.initConfig(ResinEmbed.java:520)
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:344)
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)

Resin on JamVm

Resin fails to startup on JamVM. Log below:

pi@raspberrypi ~/resin-lite $ java -jamvm -jar resin-lite.jar webtest.war 
ResinLite starting at Tue, 08 Jan 2013 14:08:34 -0500 (EST)
jmm_GetBoolAttribute: Unknown attribute 24
jmm_GetBoolAttribute: Unknown attribute 25
jmm_GetMemoryUsage
java.lang.NullPointerException
  at com.caucho.db.block.BlockManager.getMaxMemory(BlockManager.java:135)
  at com.caucho.db.block.BlockManager.defaultCapacity(BlockManager.java:104)
  at com.caucho.db.block.BlockManager.create(BlockManager.java:89)
  at com.caucho.server.resin.ResinDelegate$BlockManagerMemoryFreeTask.<init>(ResinDelegate.java:396)
  at com.caucho.server.resin.ResinDelegate.addPreTopologyServices(ResinDelegate.java:380)
  at com.caucho.server.resin.Resin.preConfigureInit(Resin.java:760)
  at com.caucho.server.resin.Resin.<init>(Resin.java:248)
  at com.caucho.server.resin.ResinEmbedded.<init>(ResinEmbedded.java:46)
  at com.caucho.server.resin.ResinEmbeddedLite.<init>(ResinEmbeddedLite.java:41)
  at com.caucho.resin.ResinLite.createResin(ResinLite.java:109)
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:335)
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)
Exception in thread "main" java.lang.UnsatisfiedLinkError: registerNatives
  at java.lang.invoke.MethodHandleNatives.registerNatives(Native Method)
  at java.lang.invoke.MethodHandleNatives.<clinit>(MethodHandleNatives.java:127)
  at java.lang.invoke.MemberName.<init>(MemberName.java:352)
  at java.lang.invoke.MethodHandles$Lookup.unreflect(MethodHandles.java:960)
  at com.caucho.config.attribute.SetterAttribute.<init>(SetterAttribute.java:55)
  at com.caucho.config.type.InlineBeanType.addProp(InlineBeanType.java:892)
  at com.caucho.config.type.InlineBeanType.introspectMethods(InlineBeanType.java:847)
  at com.caucho.config.type.InlineBeanType.introspect(InlineBeanType.java:607)
  at com.caucho.config.type.ConfigType.carefulIntrospect(ConfigType.java:68)
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:593)
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
  at com.caucho.config.xml.XmlBeanAttribute.<init>(XmlBeanAttribute.java:57)
  at com.caucho.config.xml.XmlBeanAttribute.<clinit>(XmlBeanAttribute.java:49)
  at com.caucho.config.type.EnvironmentBeanType.<init>(EnvironmentBeanType.java:57)
  at com.caucho.config.type.TypeFactory.createType(TypeFactory.java:626)
  at com.caucho.config.type.TypeFactory.getConfigTypeImpl(TypeFactory.java:586)
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:193)
  at com.caucho.config.type.TypeFactory.getType(TypeFactory.java:183)
  at com.caucho.config.xml.XmlConfigContext.configure(XmlConfigContext.java:241)
  at com.caucho.config.Config.configure(Config.java:324)
  at com.caucho.config.Config.configure(Config.java:254)
  at com.caucho.server.resin.BootConfig.configureFile(BootConfig.java:132)
  at com.caucho.server.resin.Resin.configureFile(Resin.java:1023)
  at com.caucho.resin.ResinEmbed.initConfig(ResinEmbed.java:520)
  at com.caucho.resin.ResinEmbed.start(ResinEmbed.java:344)
  at com.caucho.resin.ResinLite.main(ResinLite.java:82)

Resin Lite on Oracle JDK 7

Resin starts up with warning and seems to run OK on Oracle JDK 7. I can't use -server, but that was already established previously and not required anyway.

It's complaining about missing a JSF library, which it is since I did not include javax.faces jar. Log below...

pi@raspberrypi ~/resin-lite $ /usr/jdk1.7.0_10/bin/java -jar resin-lite.jar webtest.war 
ResinLite starting at Tue, 08 Jan 2013 14:23:39 -0500 (EST)
13-01-08 14:24:00.274 [main] INFO ResinSystem - 
13-01-08 14:24:00.283 [main] INFO ResinSystem - Resin-7.0.s130102 (built Wed, 02 Jan 2013 06:01:05 EST)
13-01-08 14:24:00.288 [main] INFO ResinSystem - 
13-01-08 14:24:00.300 [main] INFO ResinSystem - Linux 3.2.27+ arm
13-01-08 14:24:00.307 [main] INFO ResinSystem - Java(TM) SE Runtime Environment 1.7.0_10-b18, UTF-8, en
13-01-08 14:24:00.319 [main] INFO ResinSystem - Java HotSpot(TM) Client VM 23.6-b04, 32, mixed mode, Oracle Corporation
13-01-08 14:24:00.324 [main] INFO ResinSystem - 
13-01-08 14:24:00.330 [main] INFO ResinSystem - user.name  = pi
13-01-08 14:24:01.998 [main] INFO Table - Table[mnode:2] validating indexes due to unclean shutdown.
13-01-08 14:24:02.285 [main] INFO Table - Table[data:3] validating indexes due to unclean shutdown.
13-01-08 14:24:02.668 [main] INFO ServletService - 
13-01-08 14:24:02.673 [main] INFO ServletService - resin.home = /home/pi/resin-lite
13-01-08 14:24:02.679 [main] INFO ServletService - resin.root = /home/pi/resin-lite
13-01-08 14:24:02.696 [main] INFO ServletService - resin.conf = /home/pi/resin-lite/conf/resin.conf
13-01-08 14:24:02.702 [main] INFO ServletService - 
13-01-08 14:24:02.727 [main] INFO ServletService - server    = 127.0.0.1:-1 (:default)
13-01-08 14:24:02.734 [main] INFO ServletService - stage      = production
13-01-08 14:24:05.028 [main] INFO Host - Host[production/host/default] active
13-01-08 14:24:05.042 [main] INFO ServletService - ServletService[id=default,cluster=] active
13-01-08 14:24:05.064 [main] INFO NetworkListenSystem - 
13-01-08 14:24:05.169 [main] INFO TcpPort - http listening to *:8080
13-01-08 14:24:06.096 [main] INFO NetworkListenSystem - 
13-01-08 14:24:06.139 [main] INFO Resin - ResinEmbeddedLite[id=default] started in 21030ms
13-01-08 14:24:10.427 [main] WARNING JniTroubleshoot - Unable to find native library 'resin_os' for com.caucho.loader.ClassEntry. Resin expects to find this library in:
                      (Unix) /home/pi/resin-lite/libexec/libresin_os.so
                    On Unix, run ./configure --prefix=`pwd`; make; make install.
                    
                    The JVM exception was: java.lang.UnsatisfiedLinkError: Can't load library: /home/pi/resin-lite/webtest/libexec/libresin_os.so
                    
13-01-08 14:24:11.904 [main] WARNING DynamicClassLoader - java.lang.NoClassDefFoundError: javax/faces/application/ViewHandlerWrapper
                      while loading com.caucho.server.cdi.ConversationJsfViewHandler (in RootDynamicClassLoader[])
13-01-08 14:24:12.217 [main] INFO WebApp - WebApp[production/webapp/default/ROOT] active
13-01-08 14:27:18.415 [6] INFO TldManager - Loading .tld files from global classpath

Wireless

I purchased this cute little USB Wifi adapter from Adafruit for only $12. What a pain to setup if you don't use outdated WEP or WPA wireless networking. I use WPA2 with AES/CCMP (like everyone really really should be). Here's my config that finally worked using Raspbian Wheezy 2012-12-16 (not Occidentalis). (At the time of writing this, Occidentalis is a few releases behind Raspbian. Plus I was getting very weird keyboard ghosting using Occidentalis. Not sure why but it doesn't happen with Rasbian.)

I did NOT have to install any drivers.

pi@raspberrypi ~ $ cat /etc/network/interfaces 
auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet dhcp
pi@raspberrypi ~ $ sudo cat /etc/wpa_supplicant/wpa_supplicant.conf 
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
	ssid="your_sid"
	#psk="wireless password"
	psk=generated_by_wpa_passphrase
	proto=RSN
	key_mgmt=WPA-PSK
	pairwise=CCMP
	auth_alg=OPEN
}

I found you can put your wireless password in for "psk", but I don't like having passwords in clear text. So run "wpa_passphrase <sid> <password>" it generates a psk you can use instead

wpa_supplicant reference: [7]

pi@raspberrypi ~ $ sudo ifconfig -a
eth0      Link encap:Ethernet  HWaddr b8:27:eb:c7:9c:8a  
         UP BROADCAST MULTICAST  MTU:1500  Metric:1
         RX packets:10621 errors:0 dropped:0 overruns:0 frame:0
         TX packets:3979 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000 
         RX bytes:4256838 (4.0 MiB)  TX bytes:533647 (521.1 KiB)

lo        Link encap:Local Loopback  
         inet addr:127.0.0.1  Mask:255.0.0.0
         UP LOOPBACK RUNNING  MTU:16436  Metric:1
         RX packets:0 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0 
         RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr 00:e0:4c:10:47:f2  
         inet addr:192.168.1.16  Bcast:192.168.1.255  Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
         RX packets:4761 errors:0 dropped:7099 overruns:0 frame:0
         TX packets:237 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000 
         RX bytes:915418 (893.9 KiB)  TX bytes:39607 (38.6 KiB)

sddd

I've written a nice little script for OSX to help in imaging an SD card. See sdd - Paul's dd for SD Card script for OSX

Personal tools
TOOLBOX
LANGUAGES