Java SE Embedded package for Synology NAS

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. In compliance with the Oracle EULA 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 (DSM 4.3 later included this). Timezone support is also configured.

This package installs Java SE Embedded which is purposefully designed to run on low specification headless hardware. It should be noted that Synology Java Manager (only available on Intel products) is the full Java Runtime Environment, and consequently uses more RAM. By default you should use Java 8, unless the application you want to run specifically requires Java 7. Please note that Oracle ceased maintaining Java 6 in 2012, so it should be considered a serious security vulnerability. The Java 6 package has been withdrawn from the package repository for this reason. If you need it to run a particular piece of software you may download it here for manual installation.

Java Package



  • In Synology DSM’s Package Center, click Settings and add my package repository:
    Add Package Repository
  • The repository will push its certificate automatically to the NAS, which is used to validate package integrity. Set the Trust Level to Synology Inc. and trusted publishers:
    Trust Level
  • Now browse the Community section in Package Center to install a Java SE Embedded package. The repository only displays packages which are compatible with your specific model of NAS. If you don’t see Java Embedded in the list, then either your NAS model or your DSM version are not supported at this time.
  • 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 the appropriate version of Java SE Embedded for your CPU architecture and save in the public shared folder on your NAS. Note that to get any version of Java older than the current one you will need to follow the Oracle Java SE Embedded Downloads Archive link on that page. If in doubt, attempt to install the package first, and the error message will tell you which specific download version is required.
  • 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. Use Firefox if all else fails.

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.


#--------JAVA installer script
#--------package maintained at

COMMENT="# Synology Java Package"
SYNO_CPU_ARCH="`uname -m`"
[ "`echo ${SYNO_CPU_ARCH} | cut -c1-7`" == "armv5te" ] && SYNO_CPU_ARCH="armv5tel"
[ "${SYNOPKG_DSM_ARCH}" == "armada375" ] && SYNO_CPU_ARCH="armv7l-neon"
[ "${SYNOPKG_DSM_ARCH}" == "comcerto2k" ] && SYNO_CPU_ARCH="armv7l-neon"
[ "${SYNOPKG_DSM_ARCH}" == "alpine" ] && SYNO_CPU_ARCH="armv7l-neon"
[ "${SYNOPKG_DSM_ARCH}" == "alpine4k" ] && SYNO_CPU_ARCH="armv7l-neon"
[ "${SYNO_CPU_ARCH}" == "x86_64" ] && SYNO_CPU_ARCH="i686"

if [ "${SYNOPKG_PKGNAME}" == "java6" ]; then
  if [ "`echo ${SYNO_CPU_ARCH} | cut -c1-7`" == "armv5te" ]; then
    JAVA_BUILD="ARMv5 Linux - Headless EABI"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l" ]; then
    JAVA_BUILD="ARMv6/7 Linux - Headless EABI, VFP, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "i686" ]; then
    JAVA_BUILD="x86 Linux Small Footprint - Headless"
  elif [ "${SYNO_CPU_ARCH}" == "ppc" ]; then
    JAVA_BUILD="Power Architecture Linux - Headless - e500v2 core"

elif [ "${SYNOPKG_PKGNAME}" == "java7" ]; then
  if [ "${SYNO_CPU_ARCH}" == "armv5tel" ]; then
    JAVA_BUILD="ARMv5 Linux - Headless EABI, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l" ]; then
    JAVA_BUILD="ARMv6/7 Linux - Headless - Client Compiler EABI, VFP, SoftFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l-neon" ]; then
    JAVA_BUILD="ARMv6/7 Linux - Headless - Client Compiler EABI, VFP, HardFP ABI, Little Endian"
  elif [ "${SYNO_CPU_ARCH}" == "i686" ]; then
    JAVA_BUILD="x86 Linux Small Footprint - Headless"  
  elif [ "${SYNO_CPU_ARCH}" == "ppc" ]; then
    JAVA_BUILD="Power Architecture Linux - Headless - e500v2 with double-precision SPE Floating Point Unit"

elif [ "${SYNOPKG_PKGNAME}" == "java8" ]; then
  if [ "${SYNO_CPU_ARCH}" == "armv5tel" ]; then
    JAVA_BUILD="ARMv5/ARMv6/ARMv7 Linux - SoftFP ABI, Little Endian 2"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l" ]; then
    JAVA_BUILD="ARMv5/ARMv6/ARMv7 Linux - SoftFP ABI, Little Endian 2"
  elif [ "${SYNO_CPU_ARCH}" == "armv7l-neon" ]; then
    JAVA_BUILD="ARMv6/ARMv7 Linux - VFP, HardFP ABI, Little Endian 1"
  elif [ "${SYNO_CPU_ARCH}" == "i686" ]; then
    JAVA_BUILD="x86 Linux Small Footprint - Headless"
  elif [ "${SYNO_CPU_ARCH}" == "ppc" ]; then
    #Oracle have discontinued Java 8 for PowerPC after update 6
    JAVA_BUILD="Power Architecture Linux - Headless - e500v2 with double-precision SPE Floating Point Unit"

JAVA_BINARY=`echo ${JAVA_BINARY} | cut -f1 -d'.'`
PUBLIC_FOLDER="`synoshare --get public | sed -r "/Path/!d;s/^.*\[(.*)\].*$/\1/"`"
TEMP_FOLDER="`find / -maxdepth 2 -path '/volume?/@tmp' | head -n 1`"
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 ()
  synoshare -get public > /dev/null || (
    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


  if [ -n "${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
  [ -f ${PUBLIC_FOLDER}/${JAVA_BINARY}.tar.tar ] && 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

    WGET_FILENAME="`echo ${WGET_URL} | sed -r "s%^.*/(.*)%\1%"`"
    wget ${WGET_URL}
    if [[ $? != 0 ]]; then
      if [ -d ${PUBLIC_FOLDER} ] && [ -f ${PUBLIC_FOLDER}/${WGET_FILENAME} ]; then
        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
  exit 0

postinst ()
  #ldd tool is very useful but not included in DSM
  if [ ! -e /usr/local/bin/ldd ]; then
    mkdir -p /usr/local/bin
    cp ${SYNOPKG_PKGDEST}/tools/ldd-${SYNO_CPU_ARCH} /usr/local/bin/ldd

  #extract native binaries if needed
  if [ -e ${TEMP_FOLDER}/${NATIVE_BINS_FILE} ]; then
    #older DSM tar uses different command line switch for xz archives

  #extract Java (Web browsers love to interfere with .tar.gz files)
  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
    tar xzf ${JAVA_BINARY}.gz
  elif [ -f ${JAVA_BINARY}.tar ]; then
    tar xf ${JAVA_BINARY}.tar
  elif [ -f ${JAVA_BINARY}.tar.tar ]; then
    #Internet Explorer
    tar xzf ${JAVA_BINARY}.tar.tar
  #install Java
  if [ "${EXTRACTED_FOLDER}" != "${EXTRACTED_FOLDER/jdk/}" ]; then
  #change owner of folder tree
  chown -R root:root ${SYNOPKG_PKGDEST}

  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 "/${COMMENT}/d" /etc/profile
  sed -i "/${COMMENT}/d" /root/.profile

  #leave locale support in place on older DSM versions - too risky to delete system binaries
  exit 0


JRE_PATH="`find ${SYNOPKG_PKGDEST} -name jre`"
COMMENT="# Synology Java Package"
#set the current timezone for Java so that log timestamps are accurate, modern timezone names so DST works
SYNO_TZ=`cat /etc/synoinfo.conf | grep timezone | cut -f2 -d'"'`
#fix for DST time in DSM 5.2 thanks to MinimServer Syno package author
[ -e /usr/share/zoneinfo/Timezone/synotztable.json ] \
 && SYNO_TZ=`jq ".${SYNO_TZ} | .nameInTZDB" /usr/share/zoneinfo/Timezone/synotztable.json | sed -e "s/\"//g"` \
 || SYNO_TZ=`grep "^${SYNO_TZ}" /usr/share/zoneinfo/Timezone/tzname | sed -e "s/^.*= //"`

EnvCheck ()
#updates to DSM will reset these changes so check them each startup 
  #/etc/profile should contain 5 lines added by this package tagged with trailing comments
  COUNT=`grep -c "$COMMENT$" /etc/profile`
  if [ $COUNT != 5 ]; then

    #remove any existing mods
    sed -i "/${COMMENT}/d" /etc/profile

    #add required environment variables
    echo "PATH=\$PATH:${JRE_PATH}/bin ${COMMENT}" >> /etc/profile
    echo "JAVA_HOME=${JRE_PATH} ${COMMENT}" >> /etc/profile
    echo "CLASSPATH=.:${JRE_PATH}/lib ${COMMENT}" >> /etc/profile
    echo "LANG=en_US.utf8 ${COMMENT}" >> /etc/profile
    echo "export CLASSPATH JAVA_HOME LANG PATH ${COMMENT}" >> /etc/profile

  #/root/.profile should contain 3 lines added by this package tagged with trailing comments
  COUNT=`grep -c "$COMMENT$" /root/.profile`
  if [ $COUNT != 3 ]; then

    #remove any existing mods
    sed -i "/${COMMENT}/d" /root/.profile

    #add required environment variables
    echo "PATH=\$PATH:${JRE_PATH}/bin ${COMMENT}" >> /root/.profile
    echo "TZ='${SYNO_TZ}' ${COMMENT}" >> /root/.profile
    echo "export PATH TZ ${COMMENT}" >> /root/.profile

  #timezone needs setting each startup in case system value has changed
  sed -i "s%^TZ=.* ${COMMENT}%TZ='${SYNO_TZ}' ${COMMENT}%" /root/.profile

  #DSM versions older than 4.3 need locale support adding
  if [ ! -e /usr/bin/locale ]; then

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

  #DSM versions up to 5.1 are missing the zoneinfo timezone definitions which causes inaccurate log timestamps
  #thanks to CoolRaoul here:
  #to revert, just remove everything apart from 'Timezone' '' from /usr/share/zoneinfo
  if [ ! -e /usr/share/zoneinfo/Europe/London ]; then
    cp -R ${SYNOPKG_PKGDEST}/zoneinfo/* /usr/share/zoneinfo/


case $1 in
    source /etc/profile
    source /root/.profile

    #evidence of whether Java can start successfully is written to the package log
    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

    exit 0

    exit 0

    source /etc/profile
    source /root/.profile
    if [ -e "${JAVA_HOME}/bin/java" ]; then
      exit 0
      exit 1

    echo "${SYNOPKG_PKGDEST}/output.log"
    exit 0



  • 0035 05/Nov/15 – Updated to Java 8u65
  • 0034 19/Aug/15 – Fixed timezone DST issue with DSM 5.2
  • 0033 07/Aug/15 – Updated to Java 8u51, PowerPC build remains at 8u6
  • 0032 13/Jul/15 – Fixed timezone issue with DSM 5.2, updated main blog post documentation
  • 0031 25/Jan/15 – Fixed issue with version 0030 for systems with more than one volume
  • 0030 21/Jan/15 – Improved temp folder detection, updated to Java 7u75 and Java 8u33 (Oracle did not publish a version for PowerPC)
  • 0029 25/Dec/14 – DSM timezone file is no longer overwritten, which had been prompting a malware alert in DSM 5.1 Security Advisor
  • 0028 20/Oct/14 – Updated to Java 7u71, added missing zoneinfo timezone definitions to fix inaccurate timestamps for non-GMT timezones (checked every startup), switched native binary archives from .tgz to .tar.xz format to reduce size
  • 0027 18/Oct/14 – Updated Java 8 to 8u6, added support for Mindspeed Comcerto 2000 CPU in DS414j for Java 7 and Java 8
  • 0026 24/Jun/14 – DSM updates will no longer break Java
  • 0025 31/May/14 – Updated to Java 7u60
  • 0024 31/May/14 – Updated to Java 7u55
  • 0023 27/May/14 – Added Java 8 support
  • 0022 30/Jan/14 – Updated to Java 7u51
  • 0021 15/Nov/13 – Locale support is no longer downloaded and added to DSM 4.3 or newer since it’s already present
  • 0020 30/Oct/13 – 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 17/Oct/13 – Updated to Java 7u45
  • 0018 11/Oct/13 – Updated to Java 7u40, and JDK8 Early Access b106
  • 0017 05/Jun/13 – 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 21/May/13 – Added Armada370 CPU support (DS213j)
  • 0015 18/Apr/13 – Updated to Java 7u21, Java 6 Embedded seems to be no longer maintained by Oracle
  • 0014 13/Feb/13 – Fixed metadata for DSM 4.2 Package Center
  • 013 13/Dec/12 – Updated to Java 6u38 and Java 7u10
  • 012 10/Dec/12 – 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 23/Aug/11 – 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!)

990 thoughts on “Java SE Embedded package for Synology NAS

  1. synolova

    using openhab here.
    had the same problem with 1 hour time difference in java applications compared to system.

    changed file

    SYNO_TZ=`grep “^${SYNO_TZ}” /usr/share/zoneinfo/Timezone/tzname | sed -e “s/^.*= //”`
    SYNO_TZ=`grep “^${SYNO_TZ}” /usr/share/zoneinfo/Timezone/tzlist | sed -e “s/^.*= //”`



Leave a Reply

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

You are commenting using your 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