Java SE Embedded package for Synology NAS

UPDATE 3 – Now with Java 8, and full support for all versions on Intel CPUs running DSM 5.0!
UPDATE 2 – Now running on PowerPC 2010 Synology models running DSM 5.0 beta!
UPDATE – Now running on Armada 370/XP (ARMv7) and Intel Atom Evansport CPUs, as used in some x14 series Synology models!

There is a lot of good Java software, but it’s difficult to get Java running on a NAS. I decided to do something about that, mainly to pave the way for a Serviio package that didn’t require a huge guide to install. To stay legal, I followed how QNAP packaged Java for their NAS products. The Java binaries cannot be redistributed so this package looks for the downloaded .tar.gz archive in the public shared folder on the NAS. The end user is required to register with Oracle to get the file, as you can see from the description below. I also added locale support to the underlying Linux since Java requires this for UTF-8 support when reading from the filesystem.

Only Marvell Kirkwood, Marvell Armada 370/XP, Intel, and Freescale QorIQ/PowerQUICC PowerPC CPUs are supported, so please check which CPU your NAS has. Java 7 for Intel Atom CPU does not currently work on Synology systems running DSM versions older than 5.0, so those users are limited to Java 6. Though Oracle have published a JRE for PowerPC, it also requires DSM 5.0. PowerQUICC PowerPC synos running older DSM versions do not have a recent enough glibc version (2.3.4, but Oracle’s Java needs 2.4). It is technically possible to run Java on those units, but it requires chroot-ing to a Debian install which can get complicated. Christophe from chreggy.fr has recently released packages to automate this.

Java package for Synology

 

Instructions

  • If you have a multi-bay NAS, use the Shared Folder control panel to create a shared folder called public (it must be all lower case). On single bay models this is created by default. Assign it with Read/Write privileges for everyone.
  • Register with Oracle and download Java SE for Embedded 7 for either ARMv5, ARMv7 Headless Server, or PowerPC e500v2 as appropriate (Intel NAS users will need the end-of-life Java SE for Embedded 6), and save in the public shared folder. If the file isn’t found an error message will display the full expected filename. You cannot use a different version by renaming it, since the folder structure inside the archive will be different.
  • Install the Java package from the DSM Package Center. In Settings -> Package Sources add my package repository URL which is http://packages.pcloadletter.co.uk. My packages will appear in the Community section once the repo URL is added.
  • If you have trouble getting the Java archive recognised, try downloading it with a different web browser. Some browsers try to help by uncompressing the file, or renaming it without warning. I have tried to code around most of these behaviours.
  • The package does not need to start, just installing it is sufficient.
  • If you update DSM later, you will need to re-install this package or else UTF-8 and locale support will be broken by the update.
 

Package scripts

For information, here are the package scripts so you can see what it’s going to do. You can learn more about how Synology packages work by reading the Synology Package wiki.

installer.sh

#!/bin/sh

#--------JAVA installer script
#--------package maintained at pcloadletter.co.uk

SYNO_CPU_ARCH="`uname -m`"
[ "${SYNO_CPU_ARCH}" == "x86_64" ] && SYNO_CPU_ARCH="i686"
[ "`echo ${SYNO_CPU_ARCH} | cut -c1-7`" == "armv5te" ] && SYNO_CPU_ARCH="armv5tel"
if [ "${SYNOPKG_PKGNAME}" == "java6" ]; then
  DOWNLOAD_URL="http://tinyurl.com/javaembedarchive"
  EXTRACTED_FOLDER="ejre1.6.0_38"
  if [ "`echo ${SYNO_CPU_ARCH} | cut -c1-7`" == "armv5te" ]; then
    JAVA_BINARY="ejre-1_6_0_38-fcs-b05-linux-arm-sflt-eabi-headless-13_nov_2012.tar.gz"
    JAVA_BUILD="ARMv5 Linux - Headless EABI"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l" ]; then
    JAVA_BINARY="ejre-1_6_0_38-fcs-b05-linux-arm-vfp-eabi-headless-13_nov_2012.tar.gz"
    JAVA_BUILD="ARMv6/7 Linux - Headless EABI, VFP, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "i686" ]; then
    JAVA_BINARY="ejre-1_6_0_38-fcs-b05-linux-i586-headless-13_nov_2012.tar.gz"
    JAVA_BUILD="x86 Linux Small Footprint - Headless"
  elif [ "${SYNO_CPU_ARCH}" == "ppc" ]; then
    JAVA_BINARY="ejre-1_6_0_38-fcs-b05-linux-ppc-e500v2-headless-13_nov_2012.tar.gz"
    JAVA_BUILD="Power Architecture Linux - Headless - e500v2 core"
  fi    
elif [ "${SYNOPKG_PKGNAME}" == "java7" ]; then
  DOWNLOAD_URL="http://tinyurl.com/javaembed"
  EXTRACTED_FOLDER="ejre1.7.0_55"
  if [ "${SYNO_CPU_ARCH}" == "armv5tel" ]; then
    JAVA_BINARY="ejre-7u55-fcs-b13-linux-arm-sflt-headless-17_mar_2014.tar.gz"
    JAVA_BUILD="ARMv5 Linux - Headless EABI, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l" ]; then
    JAVA_BINARY="ejre-7u55-fcs-b13-linux-arm-vfp-sflt-client_headless-17_mar_2014.tar.gz"
    JAVA_BUILD="ARMv6/7 Linux - Headless - Client Compiler EABI, VFP, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "i686" ]; then
    JAVA_BINARY="ejre-7u55-fcs-b13-linux-i586-headless-17_mar_2014.tar.gz"
    JAVA_BUILD="x86 Linux Small Footprint - Headless"
  elif [ "${SYNO_CPU_ARCH}" == "ppc" ]; then
    JAVA_BINARY="ejre-7u55-fcs-b13-linux-ppc-e500v2-headless-17_mar_2014.tar.gz"
    JAVA_BUILD="Power Architecture Linux - Headless - e500v2 with double-precision SPE Floating Point Unit"
  fi
elif [ "${SYNOPKG_PKGNAME}" == "java8" ]; then
  DOWNLOAD_URL="http://tinyurl.com/javaembed"
  EXTRACTED_FOLDER="ejdk1.8.0"
  if [ "${SYNO_CPU_ARCH}" == "armv5tel" ]; then
    JAVA_BINARY="ejdk-8-fcs-b132-linux-arm-sflt-03_mar_2014.tar.gz"
    JAVA_BUILD="ARMv5 Linux - Headless EABI, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l" ]; then
    JAVA_BINARY="ejdk-8-fcs-b132-linux-arm-vfp-sflt-03_mar_2014.tar.gz"
    JAVA_BUILD="ARMv6/7 Linux - VFP, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "i686" ]; then
    JAVA_BINARY="ejdk-8-fcs-b132-linux-i586-03_mar_2014.tar.gz"
    JAVA_BUILD="x86 Linux Small Footprint - Headless"
  elif [ "${SYNO_CPU_ARCH}" == "ppc" ]; then
    JAVA_BINARY="ejdk-8-fcs-b132-linux-ppc-e500v2-03_mar_2014.tar.gz"
    JAVA_BUILD="Power Architecture Linux - Headless - e500v2 with double-precision SPE Floating Point Unit"
  fi
fi
JAVA_BINARY=`echo ${JAVA_BINARY} | cut -f1 -d'.'`
PUBLIC_FOLDER="`cat /usr/syno/etc/smb.conf | sed -r '/\/public$/!d;s/^.*path=(\/volume[0-9]{1,4}\/public).*$/\1/'`"
TEMP_FOLDER="`find / -maxdepth 2 -name '@tmp' | head -n 1`"
NATIVE_BINS_URL="http://packages.pcloadletter.co.uk/downloads/java-native-${SYNO_CPU_ARCH}.tgz"   
NATIVE_BINS_FILE="`echo ${NATIVE_BINS_URL} | sed -r "s%^.*/(.*)%\1%"`"
#DSM versions older than 4.3 need locale support adding, don't download unless needed
[ ! -e /usr/bin/locale ] && INSTALL_FILES="${NATIVE_BINS_URL}"
source /etc/profile


preinst ()
{
  if [ -z ${PUBLIC_FOLDER} ]; then
    echo "A shared folder called 'public' could not be found - note this name is case-sensitive. "
    echo "Please create this using the Shared Folder DSM Control Panel and try again."
    exit 1
  fi

  JAVA_BINARY_FOUND=

  if [ ! -z ${JAVA_HOME} ]; then
    echo "It seems from /etc/profile that a Java Runtime is already installed at ${JAVA_HOME}. Uninstall it and try again."
    exit 1
  fi
  
  [ -f ${PUBLIC_FOLDER}/${JAVA_BINARY}.tar.gz ] && JAVA_BINARY_FOUND=true
  [ -f ${PUBLIC_FOLDER}/${JAVA_BINARY}.tar ] && JAVA_BINARY_FOUND=true
  [ -f ${PUBLIC_FOLDER}/${JAVA_BINARY}.tar.tar ] && JAVA_BINARY_FOUND=true
  [ -f ${PUBLIC_FOLDER}/${JAVA_BINARY}.gz ] && JAVA_BINARY_FOUND=true
  
  if [ -z ${JAVA_BINARY_FOUND} ]; then
    echo "Java binary bundle not found. " > $SYNOPKG_TEMP_LOGFILE
    echo "I was expecting the file ${PUBLIC_FOLDER}/${JAVA_BINARY}.tar.gz. "
    echo "Please agree to the Oracle licence at ${DOWNLOAD_URL}, then download the '${JAVA_BUILD}' package"
    echo "and place it in the 'public' shared folder on your NAS. This download cannot be automated even if "
    echo "displaying a package EULA could potentially cover the legal aspect, because files hosted on Oracle's "
    echo "server are protected by a session cookie requiring a JavaScript enabled browser."
    exit 1
  fi

  cd ${TEMP_FOLDER}
  for WGET_URL in ${INSTALL_FILES}
  do
    WGET_FILENAME="`echo ${WGET_URL} | sed -r "s%^.*/(.*)%\1%"`"
    [ -f ${TEMP_FOLDER}/${WGET_FILENAME} ] && rm ${TEMP_FOLDER}/${WGET_FILENAME}
    wget ${WGET_URL}
    if [[ $? != 0 ]]; then
      if [ -d ${PUBLIC_FOLDER} ] && [ -f ${PUBLIC_FOLDER}/${WGET_FILENAME} ]; then
        cp ${PUBLIC_FOLDER}/${WGET_FILENAME} ${TEMP_FOLDER}
      else     
        echo "There was a problem downloading ${WGET_FILENAME} from the official download link, "
        echo "which was \"${WGET_URL}\" "
        echo "Alternatively, you may download this file manually and place it in the 'public' shared folder. "
        exit 1
      fi
    fi
  done
  
  exit 0
}


postinst ()
{
  WORKING_DIR=`pwd`
  
  #ldd tool is very useful but not included in DSM
  [ ! -e /bin/ldd ] && cp ${SYNOPKG_PKGDEST}/tools/ldd-${SYNO_CPU_ARCH} /bin/ldd

  #DSM versions older than 4.3 need locale support adding
  if [ ! -e /usr/bin/locale ]; then
    #extract native binaries
    cd ${SYNOPKG_PKGDEST}
    tar xzf ${TEMP_FOLDER}/${NATIVE_BINS_FILE} && rm ${TEMP_FOLDER}/${NATIVE_BINS_FILE}

    #build missing locale with UTF-8 support (don't think it matters which language)
    cp ${SYNOPKG_PKGDEST}/bin/* /bin
    cp -R ${SYNOPKG_PKGDEST}/share/i18n /usr/share
    if [ ! -d /usr/lib/locale ]; then
      mkdir /usr/lib/locale
    fi
    localedef -c -f UTF-8 -i en_US en_US.utf8
  fi  

  #extract Java (Web browsers love to interfere with .tar.gz files)
  cd ${PUBLIC_FOLDER}
  if [ -f ${JAVA_BINARY}.tar.gz ]; then
    #Firefox seems to be the only browser that leaves it alone
    tar xzf ${JAVA_BINARY}.tar.gz
  elif [ -f ${JAVA_BINARY}.gz ]; then
    #Chrome
    tar xzf ${JAVA_BINARY}.gz
  elif [ -f ${JAVA_BINARY}.tar ]; then
    #Safari
    tar xf ${JAVA_BINARY}.tar
  elif [ -f ${JAVA_BINARY}.tar.tar ]; then
    #Internet Explorer
    tar xzf ${JAVA_BINARY}.tar.tar
  fi
  
  #install Java
  if [ "${EXTRACTED_FOLDER}" != "${EXTRACTED_FOLDER/jdk/}" ]; then
    mv ${EXTRACTED_FOLDER} ${SYNOPKG_PKGDEST}
    JRE_PATH="`find ${SYNOPKG_PKGDEST}/${EXTRACTED_FOLDER} -name jre`"
  else
    mv ${EXTRACTED_FOLDER} ${SYNOPKG_PKGDEST}/jre
    JRE_PATH="${SYNOPKG_PKGDEST}/jre"
  fi
  
  #modify environment variables
  echo "PATH=\$PATH:${JRE_PATH}/bin" >> /etc/profile
  echo "JAVA_HOME=${JRE_PATH}" >> /etc/profile
  echo "LANG=en_US.utf8" >> /etc/profile
  echo "export JAVA_HOME LANG PATH" >> /etc/profile
  if [ -f /opt/etc/profile ]; then
    echo "PATH=\$PATH:${JRE_PATH}/bin" >> /opt/etc/profile
    echo "JAVA_HOME=${JRE_PATH}" >> /opt/etc/profile
    echo "LANG=en_US.utf8" >> /opt/etc/profile
    echo "export JAVA_HOME LANG PATH" >> /opt/etc/profile
  fi
  echo "PATH=\$PATH:${JRE_PATH}/bin" >> /root/.profile
  
  #change owner of folder tree
  chown -R root:root ${SYNOPKG_PKGDEST}

  #set the current timezone for Java so that log timestamps are accurate
  #we need to use the modern timezone names so that Java can figure out DST
  #this should be configured in each Java daemon's start script to that changes
  #to timezone settings in DSM are reflected
  #we need to use the modern timezone names so that Java can figure out DST
  SYNO_TZ=`cat /etc/synoinfo.conf | grep timezone | cut -f2 -d'"'`
  SYNO_TZ=`grep "^${SYNO_TZ}" /usr/share/zoneinfo/Timezone/tzname | sed -e "s/^.*= //"`
  grep "^TZ=" /root/.profile > /dev/null \
   && sed -i "s%^TZ=.*$%TZ="${SYNO_TZ}"%" /root/.profile \
   || echo TZ="${SYNO_TZ}" >> /root/.profile
  echo "export JAVA_HOME LANG PATH TZ" >> /root/.profile
  
  cd ${WORKING_DIR}
  source /etc/profile
  source /root/.profile
  
  java -version > ${SYNOPKG_PKGDEST}/output.log 2>&1
  echo >> ${SYNOPKG_PKGDEST}/output.log
  echo System installed locales: >> ${SYNOPKG_PKGDEST}/output.log
  locale -a >> ${SYNOPKG_PKGDEST}/output.log
  echo >> ${SYNOPKG_PKGDEST}/output.log
  echo JAVA_HOME=$JAVA_HOME >> ${SYNOPKG_PKGDEST}/output.log
  echo TZ=$TZ >> ${SYNOPKG_PKGDEST}/output.log
  
  echo "NOTE - This package does *not* start and stop like other packages. "
  echo "Java is correctly installed if you can see the runtime and HotSpot version numbers, "
  echo "and locale information in the package Log tab."
  
  exit 0
}


preuninst ()
{
  exit 0
}


postuninst ()
{
  #clean up profile mods
  sed -i '/^PATH=\$PATH:\/.*\/@appstore\/java.*\/bin$/d' /etc/profile
  sed -i '/^JAVA_HOME=\/.*\/@appstore\/java.*\/jre$/d' /etc/profile
  sed -i '/^LANG=/d' /etc/profile
  sed -i '/^export JAVA_HOME LANG PATH/d' /etc/profile
  if [ -f /opt/etc/profile ]; then
    sed -i '/^PATH=\$PATH:\/.*\/@appstore\/java.*\/jre\/bin$/d' /opt/etc/profile
    sed -i '/^JAVA_HOME=\/.*\/@appstore\/java.*\/jre$/d' /opt/etc/profile
    sed -i '/^LANG=/d' /opt/etc/profile
    sed -i '/^export JAVA_HOME LANG PATH/d' /opt/etc/profile
  fi
  sed -i '/^PATH=\$PATH:\/.*\/@appstore\/java.*\/jre\/bin$/d' /root/.profile
  sed -i '/^TZ=/d' /root/.profile
  sed -i '/^export JAVA_HOME LANG PATH TZ/d' /root/.profile

  #remove locale stuff if the package has added it
  if [ ! -e /usr/bin/locale ]; then
    rm /bin/locale
    rm /bin/localedef
    rm -r /usr/lib/locale
    rm -r /usr/share/i18n
  fi

  exit 0
}
 

Changelog:

  • 0024 Updated to Java 7u55
  • 0023 Added Java 8 support
  • 0022 Updated to Java 7u51
  • 0021 Locale support is no longer downloaded and added to DSM 4.3 or newer since it’s already present
  • 0020 Added support for Intel Atom Evansport and Armada XP CPUs in new DSx14 products, removed Early Access JDK 8 support since it did not run on the Armada SoCs
  • 0019 Updated to Java 7u45
  • 0018 Updated to Java 7u40, and JDK8 Early Access b106
  • 0017 For Armada370 CPU changed from ARMv7 Server JVM to Client JVM since the Server one turned out to be unstable. Added support for Early Access JDK 8 for Armada 370.
  • 0016 Added Armada370 CPU support (DS213j)
  • 0015 Updated to Java 7u21, Java 6 Embedded seems to be no longer maintained by Oracle
  • 0014 Fixed metadata for DSM 4.2 Package Center
  • 013 Updated to Java 6u38 and Java 7u10
  • 012 Installer script fetches native binaries separately to reduce bandwidth on repo hosting
  • 011 Added support for Freescale QorIQ PowerPC CPUs used in some Synology x13 series products, PowerQUICC PowerPC processors in previous Synology generations with older glibc versions are not supported
  • 010 updated to Java 6u34 and Java 7u6
  • 009 corrected timezone bug for Atlantic and Pacific timezones which may have caused error messages when in fact the package had installed correctly
  • 008 unified the build scripts
  • 007 included the locale binaries to simplify installation, fixed environment variables for root user (inc. timezone with DST support), displayed Java version information and env vars in Log tab, incremented Java to latest versions 6u32 and 7u4, fixed detection of renamed .tar.gz archives downloaded by Google Chrome
  • 006 fixed path issue for root user on non-bootstrapped systems, updated info link to refer back to this page, and improved description text
  • 005 incremented JRE versions to match new releases from Oracle
  • 004 forced check for existence of ‘public’ shared folder
  • 003 fixed a stupid typo that stopped 002 from working :)
  • 002 rewrote scripts to be easier to maintain, and to allow for web browsers that untar or rename the Java and toolchain binary bundles as they’re saved
  • 001 fixed package repo support, defined as a non-runnable service, prevented more than one JRE being installed, saved files into actual package folder rather than @appstore/java now that package names can be separate from Package Center display names
  • v3 initial spk release (I think!)
 
 
About these ads

668 thoughts on “Java SE Embedded package for Synology NAS

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s