Friday, May 25, 2018

Updating Java ad hoc

If one somehow depends on Java and it's not the case of a legacy dependency which will be insulated on an island system of yet very restricted subnetwork, then it will certainly need to get Java updated from time to time, because of security fixes and required new functionalities and support. But in addition, if the system isn't a more recent Solaris 11 where one can't or doesn't want IPS taking care of the update, then it will be necessary to perform an ad hoc Java update. That's probably the case with a Solaris 11 Express system or even Solaris 10, although I do highlight that in case of a Solaris 10, perhaps fortunately there's an additional option to using the old SVr4 package system to get the update in place in a presumably easier way.

In either way, one will need to get to an official download page, preferably Oracle's, which at the time of this writing is Java SE Downloads. By accessing the official site one will also find out about the upcoming Java 10(!) but for now let's stick to the crowd at Java 8, which, by the way, has been never (at least publicly) available for a 32-bits Solaris system. But if your Solaris system is 64-bits you can get (at the time of this writing) the following publicly available Java 8 update:

jdk-8u172-solaris-x64-demos.tar.gz
148f1a7f17cba7e20ee637c8e8c9ca8ff0c9d4d409743aaa0248f6da4b9566c4

jdk-8u172-solaris-x64-demos.tar.Z (SVr4)
2cbd265f3e0a10426c29c1b5f9d5ee0e6a8aef23013395733802523043793b94

jre-8u172-solaris-x64.tar.gz
40e545260d6819ba5b73678a84662411ea8fec6629fc1bf9c4caccf18fdb0270

server-jre-8u172-solaris-x64.tar.gz
87eeeb2a3e17729b8b197493e7512a54a71ba5e5301cbadcad4063f5383db207

jdk-8u172-solaris-x64.tar.gz
7390462531c95c03ffc1e8a9b6cc2c4d0150a6c6bd0757f88243d67f04a33598

jdk-8u172-solaris-x64.tar.Z (SVr4)
f97b300af0c6f546a09f373a6af618bb29bde9302fd53ba785c416f765c4e25b

In case of a 32-bits systems, the only non-optimal risky approach (in terms of security issues) seems to be the the following latest unsupported and security flawed legacies from what I call The Java Archive.


NOTE
It may be possible, although I still couldn't dispose of enough resources to ascertain it, to manually build a 32-bits OpenJDK version. It seems that a C++11 compiler may be required, but by default no legacy system could possibly provide one, hence it's probably necessary to take care of this beforehand. For instance, by default, Solaris 11 Express IPS repository only offers GCC 3.4.3 which tops at C++98.

Now let me consider, for instance, a 1 GB RAM 32-bits host with Solaris 11 Express SRU-14, on which by default one gets the following basic status about Java:

# java -version
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07)
Java HotSpot(TM) Client VM (build 19.1-b02, mixed mode)


# pkg info java
          Name: runtime/java
       Summary: JDK 6.0 Runtime Env. (1.6.0_24)
   Description: Java Platform virtual machine and core class libraries
      Category: Development/Java
         State: Installed
     Publisher: solaris
       Version: 0.5.11
 Build Release: 5.11
        Branch: 0.151.0.1.6
Packaging Date: May  3, 2011 11:47:24 PM
          Size: 96.74 MB
          FMRI: pkg://solaris/runtime/java@0.5.11,...


As an exercise, let's try to update this legacy 32-bits Solaris 11 Express system, in order to have it use "better" ;-) legacies for Java 6 (Update 45) and Java 7 (Update 80). This procedure may also work for updating a 64-bits Solaris 11 Express with the latest Java 8 update if other systems dependencies don't get in the way.

The deployment strategy of Java seems somewhat stable, at least since Solaris 11 Express up to Solaris 11.3 GA. One typically has the following structure under the hood (not considering any other IPS facilities):

$ l /usr/java
lrwxrwxrwx ... /usr/java -> jdk/jdk1.6.0_24


$ l /usr/jdk
...
drwxr-xr-x ... instances
lrwxrwxrwx ... jdk1.6.0_24 -
> instances/jdk1.6.0
lrwxrwxrwx ... latest -> jdk1.6.0_24


$ l /usr/jdk/jdk1.6.0_24
lrwxrwxrwx ... /usr/jdk/jdk1.6.0_24 -> instances/jdk1.6.0


$ l /usr/jdk/instances
...
drwxr-xr-x ... jdk1.6.0


As seen above when IPS package for Java in Solaris 11 Express doesn't provide for multiple versions of Java. On more recent versions of Solaris 11, multiple major versions (7 and 8) are possibly installed side-by-side through the mediator IPS feature.

NOTE
Although one sees jdk everywhere above, one is actually getting just JRE from the default installation.

On the above scenario it seems the best option is:
  1. Extract the 32-bits jdk1.6.0_45 under the instances subdirectory;
  2. Create the symbolic link jdk1.6.0_45 in the jdk subdirectory
  3. Adjust the latest and java symbolic links

# cd /usr/jdk/instances

# .../jdk-6u45-solaris-i586.sh
Unpacking...
Checksumming...
Extracting...
UnZipSFX 5.32 of 3 November 1997 😲, by Info-ZIP ...
   creating: jdk1.6.0_45/
   creating: jdk1.6.0_45/jre/
   creating: jdk1.6.0_45/jre/bin/
  inflating: jdk1.6.0_45/jre/bin/java 

        ...

Creating jdk1.6.0_45/jre/lib/rt.jar
Creating jdk1.6.0_45/jre/lib/jsse.jar
Creating jdk1.6.0_45/jre/lib/charsets.jar
Creating jdk1.6.0_45/lib/tools.jar
Creating jdk1.6.0_45/jre/lib/ext/localedata.jar
Creating jdk1.6.0_45/jre/lib/plugin.jar
Creating jdk1.6.0_45/jre/lib/javaws.jar
Creating jdk1.6.0_45/jre/lib/deploy.jar
...


# chown -R root:bin jdk1.6.0_45

# cd ..

# ln -s instances/jdk1.6.0_45 jdk1.6.0_45

# rm latest
# ln -s jdk1.6.0_45 latest

# l /usr/jdk
...
drwxr-xr-x ... instances
lrwxrwxrwx ... jdk1.6.0_24 -
> instances/jdk1.6.0 
lrwxrwxrwx ... jdk1.6.0_45 -> instances/jdk1.6.0_45
lrwxrwxrwx ... latest -> jdk1.6.0_45

# cd ..

# rm java
# ln -s jdk/jdk1.6.0_45 java

# java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) Client VM (build 20.45-b01, mixed mode, sharing)


NOTE
By the way, the default of "Client VM" is not a consequence of the update. It has to do with the amount of RAM available on the machine. On a 1 GB RAM machine it defaults to "Client VM". If the machine has 2 GB RAM, it defaults to "Server VM". But I haven't located any official reference stating the precise threshold numbers that drive the exact behavior of the IF_SERVER_CLASS option used on the default jvm.cfg configuration file. I have found ways to default (jvm.cfg) or override (-client / -server) one mode or the other, as well as some command-line memory options (java -X). Of course, the "Server VM" is better suited to back-end applications, while "Client VM" is optimized for front-end GUI applications. Perhaps one may find more information at Java OTN.

Bottom line: If you read "Client VM", then your host may not have adequate memory resources to make it well suited for a back-end long-running Java applications.
NOTE
Recall that since Java 7 one has two options of JRE tarballs / packages, one of them explicitly named server-jre-... which presumably would enforce the "Server VM", as opposed to the Java 6 options mentioned above.

Except for the extraction method of the package or tarball, the procedure is virtually the same for other versions. For instance, after a manual upgrade from Java 6 (45) to Java 7 (80) one will get:

# l /usr/jdk
...
drwxr-xr-x ... instances
lrwxrwxrwx ... jdk1.6.0_24 -
> instances/jdk1.6.0 
lrwxrwxrwx ... jdk1.6.0_45 -> instances/jdk1.6.0_45
lrwxrwxrwx ... jdk1.7.0_80 -> instances/jdk1.7.0_80
lrwxrwxrwx ... latest -> jdk1.7.0_80

$ l /usr/java
lrwxrwxrwx ... /usr/java -> jdk/jdk1.7.0_80


$ java -version
java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) Server VM (build 24.80-b11, mixed mode)


Sorry IPS:

# pkg verify java
PACKAGE                         STATUS
pkg://solaris/runtime/java       ERROR
    link: usr/jdk/latest
            Target: 'jdk1.7.0_80' should be 'jdk1.6.0_24'
    link: usr/java
            Target: 'jdk/jdk1.7.0_80' should be 'jdk/jdk1.6.0_24'


Hence, as one can see things are generally easy and it's unfortunate that no more updates (security fixes) are made publicly available forcing everyone to move to 64-bits and Java 8. I agree that Java 8 on 64-bits may have wonderful new facilities and simplifcations and optimizations, but I argue that the legacy with its inherent limitations may be wonderful as well as long as it isn't security flawed, which is hard to believe too much effort would be necessary to patch it. And the same goes for other software and hardware as well.