Thursday, May 24, 2018

Updating Java via IPS

The world knows Java, for the good, and for the bad, whatever. Bottom line is one way or the other you're gonna need to handle its existence and pervasiveness. Fortunately, Java is Oracle's as well as Solaris is and thus there's an easier way of handling it via IPS, even if one doesn't have an agreement for having access to an IPS support repository. This post is about a more streamlined way of how to do it based on the article: How to Update Only Java on Your Oracle Solaris 11 System. For this post I assume just a publicly available Solaris 11.3 GA system.

I also assume a local IPS repository which could serve many local Solaris systems and I'll use "OPTION 1" (pkgrecv) as described on the previous link to update the local repository by adding the newer Java packages (at the time of this writing they were versions 1.8.0_172 and 1.7.0_101 according to the official release repository which package names were jre-7, jdk-7, jre-8 and jdk-8).

Assuming that my local repository is at /depot/solaris/11.3/GA, I'll need to carry out the following commands in order to updated it with the aforementioned packages (including any other previous version since the original GA release):

# SOURCE=http://pkg.oracle.com/solaris/release  # source repository
# TARGET=/depot/solaris/11.3/GA                 # target repository

# pkgrecv -s $URI -d $TARGET                                \
  'pkg://solaris/consolidation/java-8/java-8-incorporation' \
  'pkg://solaris/runtime/java/jre-8'                        \
  'pkg://solaris/developer/java/jdk-8'                      \
  'pkg://solaris/library/java/java-demo-8'                  \
  'pkg://solaris/consolidation/java-7/java-7-incorporation' \
  'pkg://solaris/runtime/java/jre-7'                        \
  'pkg://solaris/developer/java/jdk-7'                      \
  'pkg://solaris/library/java/java-demo-7'

# pkgrepo refresh -s $TARGET

The previous commands will trigger the download of over 2 GB which may be overkill if all that's needed is the latest versions. That's because the package names specified doesn't mention any specific version, so IPS assumes all versions except those already in the repository.

For instance, WRT Java IPS incorporations, an associated subject which I'll further expand in a moment, one would perceive such many intermediate versions:

# pkg list -af java-8-incorporation
NAME (PUBLISHER)                             VERSION            IFO
consolidation/java-8/java-8-incorporation    1.8.0.172.11-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.162.12-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.152.16-0     i--
consolidation/java-8/java-8-incorporation    1.8.0.141.15-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.131.11-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.121.13-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.112.15-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.102.14-0     ---
consolidation/java-8/java-8-incorporation    1.8.0.92.14-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.77.3-0       ---
consolidation/java-8/java-8-incorporation    1.8.0.72.15-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.66.17-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.60.27-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.51.16-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.45.14-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.40.25-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.31.13-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.25.17-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.20.26-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.11.12-0      ---
consolidation/java-8/java-8-incorporation    1.8.0.5.13-0       ---


# java -version
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)


NOTE
In the previous command one may noticed that I've already carried out this procedure in the past, since the original Solaris 11.3 GA release but before writing this post. By the time I've updated Java I've moved from the Solaris 11.3 GA released Java version of 1.8.0_60 to the more recent 1.8.0.152. But at the time I was finally documenting the procedure on this post, the update level had already bumped to 1.8.0_172 as seen above.

As far as I know there are two ways of ignoring unwanted intermediate versions up to the more recent ones:

  1. One can specify an specific version, but the disadvantage is that in general this requires one additional query to find out what versions are available, for instance @1.8.0.172.11-0.
      
  2. If one only needs the more recent version, then things are a little easier. All that's required is to use the special @latest IPS package version suffix.

Hence to ease the download burden one could use the following alternative to the previous pkgrecv command:

# pkgrecv -s $URI -d $TARGET                                       \
  'pkg://solaris/consolidation/java-8/java-8-incorporation@latest' \
  'pkg://solaris/runtime/java/jre-8@latest'                        \
  'pkg://solaris/developer/java/jdk-8@latest'                      \
  'pkg://solaris/library/java/java-demo-8@latest'                  \
  'pkg://solaris/consolidation/java-7/java-7-incorporation@latest' \
  'pkg://solaris/runtime/java/jre-7@latest'                        \
  'pkg://solaris/developer/java/jdk-7@latest'                      \
  'pkg://solaris/library/java/java-demo-7@latest

If everything went well up to this point then the local repository now contains the new packages which can be use to update all Solaris 11.3 GA systems that eventually point to it.

In order to get on such Solaris system update Java from the update repository, it's necessary to unlock the affected parts (the so-called IPS incorporations for Java) of the so-called IPS image associated to that particular system. The unlock allows the newer packages to be inserted into the image, thus updating the system at last. Since the original GA release of Solaris 11.3, Java has been undergoing a fast-paced evolution to the point that it became necessary to better handle the co-existence and transitions between major versions, 1.7 and 1.8 at this time lapse. Hence, the original 11.3 GA release Java incorporation, once called consolidation/java/java-incorporation was superseded by two major versions specific ones:
 
  • consolidation/java-7/java-7-incorporation
  • consolidation/java-8/java-8-incorporation

That is, before any Java update is performed, one should get the following from a standard Solaris 11.3 GA installation:

# pkg mediator java
MEDIATOR     VER. SRC. VERSION IMPL. SRC. IMPLEMENTATION
java         system    1.8     system


# pkg mediator -a java
MEDIATOR     VER. SRC. VERSION IMPL. SRC. IMPLEMENTATION
java         system    1.8     system    
java         system    1.7     system 


# pkg list |grep consolidation/java-
consolidation/java-7/java-7-incorporation  1.7.0.85.33-0            i--
consolidation/java-8/java-8-incorporation  1.8.0.60.27-0            i--
consolidation/java/java-incorporation      0.5.11-0.175.2.0.0.31.0  i-r


In the end, in order to assure all the required stuff is dully unlocked, I choose to unlock all of them with the following command on each Solaris system:

# pkg change-facet \
  version-lock.consolidation/java/java-incorporation=false \
  version-lock.consolidation/java-7/java-7-incorporation=false \
  version-lock.consolidation/java-8/java-8-incorporation=false

The previous command will create a new backup BE (boot environment) with the suffix -backup-#, which I prefer to rename to something more meaningful, such as:

# beadm rename \
  Solaris-11.3-GA-...-backup-# \
  Solaris-11.3-GA-...-Java-AsReleased

At this point, one should new be able to update the particular system. Assuming a default installation where no JDK is installed, just JRE one should get something similar to the following:

# pkg info -r jre-8
          Name: runtime/java/jre-8
       Summary: Java ... Runtime Environment (1.8.0_172-b11)
   Description: The Java ... Runtime Environment (JRE)...
      Category: Development/Java
         State: Not installed
     Publisher: solaris
       Version: 1.8.0.172.11
 Build Release: 5.11
        Branch: None
Packaging Date: April 10, 2018 02:33:11 AM
          Size: 154.60 MB
          FMRI: pkg://solaris/runtime/java/jre-8@1.8.0.172.11,...


# pkg info -r jdk-8
          Name: developer/java/jdk-8
       Summary: Java ... Development Kit (1.8.0_172-b11)
   Description: The Java ... Development Kit (JDK)...

        Category: Development/Java
         State: Not installed
     Publisher: solaris
       Version: 1.8.0.172.11
 Build Release: 5.11
        Branch: None
Packaging Date: April 10, 2018 02:32:44 AM
          Size: 96.43 MB
          FMRI: pkg://solaris/developer/java/jdk-8@1.8.0.172.11,...


# pkg update -nv \
  java-7-incorporation@latest \
  java-8-incorporation@latest
            Packages to update:         4
     Estimated space available:    ... GB
Estimated space to be consumed: 703.52 MB
       Create boot environment:        No
Create backup boot environment:       Yes
          Rebuild boot archive:        No

Changed packages:
solaris
  consolidation/java-7/java-7-incorporation
    1.7.0.85.33,... -> 1.7.0.101.14,...
  consolidation/java-8/java-8-incorporation
    1.8.0.60.27,... -> 1.8.0.172.11,...
  runtime/java/jre-7
    1.7.0.85.33,... -> 1.7.0.101.14,...
  runtime/java/jre-8
    1.8.0.60.27,... -> 1.8.0.172.11,...


Hence on the actual update one should provide (via the --be-name pkg update option) the new BE with a more meaningful name, perhaps something that would better reflect the changes, such as Solaris-11.3-GA-...-Java-1.7.0_85-&-1.8.0_172 or so. Once the above update completes one will get updated JRE both for Java 1.7 and Java 1.8, because as seen above, updating an incorporation, triggers the update of the respective JRE.

If, in addition, one is in "desperate" ;-) need for the JDK, then:

# pkg install -v jdk-8
           Packages to install:         2
            Packages to update:         2
     Estimated space available:  30.94 GB
Estimated space to be consumed: 518.33 MB
       Create boot environment:        No
Create backup boot environment:       Yes
          Rebuild boot archive:        No

Changed packages:
solaris
  SUNWcs
    None -> 0.5.11,...
  developer/java/jdk-8
    None -> 1.8.0.172.11,...
  consolidation/java-8/java-8-incorporation
    1.8.0.60.27,... -> 1.8.0.172.11,...
  runtime/java/jre-8
    1.8.0.60.27,... -> 1.8.0.172.11,...

DOWNLOAD            PKGS         FILES    XFER (MB)   SPEED
Completed            4/4       712/712    94.5/94.5  273k/s

PHASE                                          ITEMS
Removing old actions                             6/6
Installing new actions                       731/731
Updating modified actions                      98/98
Updating package state database                 Done
Updating package cache                           2/2
Updating image state                            Done
Creating fast lookup database                   Done
Reading search index                            Done
Updating search index                            4/4
Updating package cache                           1/1


NOTE
In the preceding command, note as the installation of the latest JDK will trigger, if needed, the update of the latest Java incorporation, which in turn will make sure the latest JRE also gets installed.

Finally, the very latest Java 8 at the time of this writing:

# java -version
java version "1.8.0_172"
Java(TM) SE Runtime Environment (build 1.8.0_172-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.172-b11, mixed mode)