Wednesday, October 14, 2015

Installing Cisco RTMT 10.5 on Apple OS X

"Could you re-post the ciscomonkey.net article covering installation of RTMT on OS X?" is a request I receive at least once a month. Well, the short answer to the question is: no, I can't repost the original content. I wasn't the original author and I am not willing to post someone else's content without their explicit consent. I doubt @ciscomonkey would mind but it still isn't cool.

That said, I have an obligation to my readers and there have been enough changes to the RTMT installer to warrant revisiting the whole process. This article provides an updated step-by-step procedure for installing RTMT on Mac OS X. The procedures cover the most recent Cisco UC applications.


Background

Any work I have done around RTMT on Mac OS X wouldn't have been possible without the work of @ciscomonkey on a blog he used to maintain (ciscomonkey.net). That site is gone now but the original process provides a good foundation. So, props given.

There have been changes along the way. When UCM 8.6 came out, there were some procedural modifications that were needed to avoid issues with loading the installer. Those modifications were originally documented by me here and eventually rolled into the original ciscomonkey.net article. 

The content provided below is based on the RTMT Linux installer from a CUCM 10.5 system and Mac OS X Mavericks. I also tested with OS X El Capitan, with some mixed results. I have a functional installation on OS X 10.11 but I encountered some procedural gaps.

For those that have attempted to load RTMT and are running into issues, you may want to jump to the "Troubleshooting" section to see if you can find a solution.

Enough background, let's get to it. 


Step 1. Download the Installation File

You can get the RTMT binary from any CUCM cluster. Simply open a web browser and go to https://publishernode/ccmadmin. Login as a user with the appropriate permissions and then go to Application > Plugins

Using the search facility find all files that contain the word "Real" (without quotes). Download the Linux binary by clicking on the appropriate download link. Save the file to the appropriate download folder on your Mac. 

Step 2. Prepare Your Environment

There are a couple of things to be mindful of and your mileage may vary. I am not a Java guru and RTMT has Java environment dependencies. I don't know them all, just the ones I have run across. 

Modify Installer Attributes

The .bin file won't run by default. You need to toggle the executable attribute on the file. To do this, launch a terminal application and go to the directory where you downloaded the binary file (I downloaded it to installfiles/cisco/rtmt/).

galactus-2:RTMT xx$cd ~/installfiles/cisco/rtmt/
galactus-2:RTMT xx$ls
CcmServRtmtPlugin-10-5-2.bin CcmServRtmtPlugin-9-1-2.exe
CcmServRtmtPlugin-9-1-2.bin
galactus-2:RTMT xx$ chmod +x ./CcmServRtmtPlugin-10-5-2.bin

Check the Java Version

To avoid running into the Unsupported major.minor version error discussed in the "Troubleshooting" section, I recommend you just implement the fix ahead of time. Either way, you'll know if you have the issue soon enough. Take a look at the fix provided at the end of this blog if you want to preemptively address the issue.

Custom Install Directory

I usually plan on having multiple RTMT versions installed at any given time. It is annoying but I just accept it as a fact of life. So, I create a custom sub-folder in my Application folder for Cisco RTMT and then I create another sub-folder for my new version. I do this ahead of time because the installer wizard is going to bulk at creating folders due to permissions issues. So, for this version of RTMT I created a new folder (/Applications/Cisco RTMT/JRTMT10.5.2/) in Finder.

Step 3. Install RTMT

To run the installer, use the following command:
sh ./CcmServRtmtPlugin-10-5-2.bin LAX_VM /usr/bin/java

The reason for specifying the VM is documented in the RTMT 8.6 blog article I published a while back. I found the installer behavior to be consistent with 9.x and 10.x installers.

This should launch the installation wizard and you are almost home. 




Walk through the wizard as you normally would. Note that if you want to use a custom directory, you'll want to create it before selecting the install directory in the wizard. Once the wizard completes the install, click on Finish.


Step 4. Modify the Run Shell Script

The "run.sh" script that is installed with RTMT uses a fully qualified path to load the Java binary. The default path isn't the same as on a typical OS X system. So, we simply have to edit the shell script to use the correct path. 

The script is installed to whatever directory you chose. On my system: 

/Applications/Cisco RTMT/JRTMT10.5.2/Jrtmt

I recommend backing up the shell script: cp run.sh run.sh.backup

Then edit the script file using vi, TextWrangler, or whatever floats your boat. We only need to change the very first part of the rather long command. Change the following:

"./jre/bin/java"  (with quotes)

TO

"/usr/bin/java"

Save your changes. If using vim from the command line, it is easy peasy:


:%s/\.\/jre\/bin/\/usr\/bin/ 
:wq


Step 5. Run Shell Script

I recommend doing this from the command line on the initial test. This will allow you to see any error messages that are generated. From terminal, change to the directory where you installed RTMT and run the shell script: ./run.sh

If you see the following, you are on the right track. Specify your host FQDN or IP address and click OK.


You should then be prompted to accept the certificate (unless it is already in your trust store).



Finally, you will be prompted to authenticate yourself.




If you run into issues, go to the troubleshooting section below. Also, double check that you followed the steps provided. 



Step 6. Create Apple Script

If you want to be able to run the RTMT application without having to load terminal then create an AppleScript. Load the AppleScript edit and type in the following:

do shell script "cd /Applications/Jrtmt; ./run.sh"

The above shows the default installation path, if you used a custom path then change the "cd" command accordingly (as shown in the following image). Run the script to make sure it works. 




Once you confirm the AppleScript is functional, save the script locally on your machine. When you save the script set the file type as Application. You may need to save it on your desktop and then copy it to your Applications folder due to Applications folder permission constraints. 

Troubleshooting

Unsupported major.minor version Error

There is an error that I ran into (and Google suggests others have, as well) where I received an error similar to the following AFTER the install but during the initial run of the shell script (run.sh). 


galactus-2:JRtmt xx$ ./run.sh
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/cisco/ccm/serviceability/rtmt/ui/JRtmtMain : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:637)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

I ran into this error on my Maverick's system. This is due to the fact the JDK version used to compile the Cisco binary is newer than the version loaded in Mac OS X. First, what the hell is major.minor version 51.0? Based on my digging, the version identifiers are defined as:

J2SE 8 = 52 (0x34 hex)
J2SE 7 = 51 (0x33 hex)
J2SE 6.0 = 50 (0x32 hex)
J2SE 5.0 = 49 (0x31 hex)
JDK 1.4 = 48 (0x30 hex)
JDK 1.3 = 47 (0x2F hex)
JDK 1.2 = 46 (0x2E hex)
JDK 1.1 = 45 (0x2D hex)

To verify what is going on, do the following. You'll notice that my Java run time environment was version 6. RTMT is compiled with version 7 and I believe that is the crux of the issue.

Check Your Current Java Version:


galactus-2:JRtmt xx$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)



Check Your Existing SDK:


galactus-2:JRtmt xx$ /usr/libexec/java_home -verbose
Matching Java Virtual Machines (2):
1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home


The Fix

There may be other ways to resolve this problem but I went ahead and installed JDK 8. From my understanding, you want to use the JDK vs. the JRE since the JDK will (a) include the JRE and (b) update the necessary symbolic links to the JRE used by OS X. 

To verify:


galactus-2:JRtmt xx$ /usr/bin/java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
galactus-2:JRtmt xx$ /usr/libexec/java_home -verbose
Matching Java Virtual Machines (3):
1.8.0_60, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home
1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

NOTE: If you had to update Java then you will most likely need to implement the following TzDataManager fix.


TzDataManager Error: NullPointerException

This error occurs after you run RTMT and provide your login credentials. So, it gets pretty far into the initialization process (or so it seems) and then pukes on you. The RTMT error is nondescript:


At the console, you will see something like this:


2015-10-10 16:44:13,908 [SplashThread] ERROR rtmt.control - TzDataManager:getStrClientTzVersion:[ERROR]:Ex: /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/zi/ZoneInfoMappings (No such file or directory)
2015-10-10 16:44:13,908 [SplashThread] ERROR rtmt.control - [ERROR] In run thread SplashWindow: java.lang.NullPointerException
2015-10-10 16:44:13,909 [SplashThread] ERROR rtmt.control - [ERROR] In run thread SplashWindow: java.lang.NullPointerException
at com.cisco.ccm.serviceability.rtmt.utils.TzDataManager.findClientTzVersion(Unknown Source)
at com.cisco.ccm.serviceability.rtmt.utils.TzDataManager.(Unknown Source)
at com.cisco.ccm.serviceability.rtmt.ui.JRtmtMain.doMeat(Unknown Source)
at com.cisco.ccm.serviceability.rtmt.ui.JRtmtMain$SplashWindow$2.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)


Basically, RTMT is looking for a file "ZoneInfoMappings" in the home environment for the Java version that we are using (i.e. Java 8, in this case). The file isn't there and that breaks things. Actually, the entire directory (zi) where RTMT is looking for the file is missing. At least, this was the issue in my environment. 

The Fix

Again, there are probably other (and better) ways to fix this issue. I fixed it by doing the following. I found the "zi" directory in my Java 6 environment and I copied the entire directory to my Java 8 environment.


galactus-2:lib xx$ /usr/libexec/java_home -verbose
Matching Java Virtual Machines (3):
1.8.0_60, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home
1.6.0_65-b14-462, x86_64: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
1.6.0_65-b14-462, i386: "Java SE 6" /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

galactus-2:lib xx$ sudo cp -R /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/zi /Library/Java/JavaVirtualMachines/jdk1.8.0_60.jdk/Contents/Home/jre/lib/


On the El Capitan test system, I had no previous Java version and I installed JDK 8. I honestly don't know if I had Java 6 on this system before I upgraded to 10.11. I found that I could workaround the issue by creating a [JavaHome]/jre/lib/zi directory and creating a blank ZoneInfoMappings file by using touch.


wolverine:lib xx$ sudo mkdir zi
Password:
wolverine:lib xx$ cd zi
wolverine:zi xx$ sudo touch ZoneInfoMappings



The above fix is suboptimal. For the life of me, I couldn't find a clean solution to download the ZoneInfoMappings and all of the time zone information files. I also tested by copying a full "zi" folder from another system. That worked. If you don't have that option then I also found that simply creating the "dummy" file as noted above was functional (albeit a bit quirky). Perhaps the answer is to download the legacy Java 6 runtime from Apple and then load JDK 8? If someone has a better handle then please post in the comments!


Thanks for reading. If you have time, post a comment!

19 comments:

  1. I have a problem with the RTMT 10.5, when I execute the ./run.sh command I can see this exception:

    xception in thread "SplashThread" java.lang.NoSuchFieldError: JAVAZM_LABEL
    at com.sun.tools.tzupdater.Utils.getTzID(Utils.java:27)
    at com.sun.tools.tzupdater.TimezoneUpdater.run(TimezoneUpdater.java:152)
    at com.sun.tools.tzupdater.TimezoneUpdater.main(TimezoneUpdater.java:539)
    at com.cisco.ccm.serviceability.rtmt.utils.TzDataManager.fnUpdateTzTables(Unknown Source)
    at com.cisco.ccm.serviceability.rtmt.utils.TzDataManager.handleTzVersionMismatch(Unknown Source)
    at com.cisco.ccm.serviceability.rtmt.ui.JRtmtMain.doMeat(Unknown Source)
    at com.cisco.ccm.serviceability.rtmt.ui.JRtmtMain$SplashWindow$2.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)

    and my RTMT freeze in "Loading, Please wait..."

    ReplyDelete
    Replies
    1. I am seeing the same exact messages with RTMT 9.1. Have you found a fix?

      Delete
    2. I have not come across this error. Can you guys provide specifics on versions (OS and UCM versions). I will try to replicate in the lab. I have El Capitan and Mavericks running (along with UCM 9.1(2) and 10.5(2)).

      I am also curious if one of the other workarounds for tzupdater would fix this issue, as well.

      HTH
      -Bill (@ucguerrilla)

      Delete
  2. Hi Bill,

    I'm on:

    OS 10.10.5

    UCM 10.5(1)

    java version "1.8.0_73"
    Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
    Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode)


    regards,
    Mike.

    ReplyDelete
    Replies
    1. Mike,

      I can't replicate this environment exactly as I am running OS X 10.11. That said, all other things being the same, I did not run into this issue.

      Not sure how to reproduce the issue. The NoSuchField error may point to an incompatibility between the compiled version of a library and the runtime version.

      More digging is required. I would check the install path for RTMT (where run.sh is stored) to see if there is a tzupdateFlag.rtmt file. If so, remove that and try again. Unlikely this is the case.

      HTH

      -Bill

      Delete
    2. Removed the tzupdateFlag.rtmt file and re-ran rtmt.
      It says timezone mismatch and prompts to update timezone - if I select no - it all works. If select yes to update, get the same NoSuchField error.

      Delete
    3. thanks for all... It works now

      Delete
    4. Was this ever resolved, Mike? I'm getting the same exact behavior and I have removed the tzupdateFlag.rtmt file. I dont know enough about Java to really be able to dig in and try to figure this out.

      Delete
    5. Below is the output while watching it try to update:

      2016-03-10 08:13:21,932 [SplashThread] INFO rtmt.control - [INFO]Timezone ServerVersion:tzdata2013i
      2016-03-10 08:13:21,932 [SplashThread] INFO rtmt.control - [INFO]Timezone ClientVersion:
      2016-03-10 08:13:21,932 [SplashThread] INFO rtmt.control - [INFO]Timezone isUpdateRequired:true
      2016-03-10 08:13:21,935 [SplashThread] INFO rtmt.control - [INFO]:TzdataManager:handleTzVersionMismatch: tzupdater.jar version matches with that of the server. Clean tzupdate can happen. hence proceeding to update tztables.
      Exception in thread "SplashThread" java.lang.NoSuchFieldError: JAVAZM_LABEL
      at com.sun.tools.tzupdater.Utils.getTzID(Utils.java:27)
      at com.sun.tools.tzupdater.TimezoneUpdater.run(TimezoneUpdater.java:152)
      at com.sun.tools.tzupdater.TimezoneUpdater.main(TimezoneUpdater.java:539)
      at com.cisco.ccm.serviceability.rtmt.utils.TzDataManager.fnUpdateTzTables(Unknown Source)
      at com.cisco.ccm.serviceability.rtmt.utils.TzDataManager.handleTzVersionMismatch(Unknown Source)
      at com.cisco.ccm.serviceability.rtmt.ui.JRtmtMain.doMeat(Unknown Source)
      at com.cisco.ccm.serviceability.rtmt.ui.JRtmtMain$SplashWindow$2.run(Unknown Source)
      at java.lang.Thread.run(Thread.java:745)

      Delete
    6. Hi CiscoDude.
      It was not really resolved as such.
      Work-around is to delete the tzupdateFlag.rtmt file where-ever you have your RTMT installed (/Applications/Cisco RTMT/JRTMT10.5.2/Jrtmt in Bill's example above) and re-run, making sure to say no to update time-zone (otherwise it writes another tzupdateFlag.rtmt file).

      Delete
  3. Ok I have El Capitan and cannot figure out where to create the directory [JavaHome]/jre/lib/zi directory and creating a blank ZoneInfoMappings file by using touch. I have rights and all the other components running. Just need this last step

    ReplyDelete
  4. Answered my own question. I looked at the results from the failure and found the right path /Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre

    ReplyDelete
  5. Hi, Wanted to tell you this is such a great thread for getting RTMT up and running on a MAC. Big help, so thanks.

    I ran into the mismatched timezone issue. I know next to nothing about using terminal in a MAC so I've been trying to figure out where my Java home directory is with no luck. I look in Library/Java and all there is in that directory is Extensions and Extensions has nothing in it when I do a ls in the directory. I've got Java 8 installed. Any ideas on how I can find this directory to create the blank ZoneInfoMappings file? Also, I tried just creating a jre/lib/zi directory in the Java directory and created the blank ZoneInfoMappings file but no such luck. Now RTMT wont go past the loading screen when I open it. I"m not literate enough in the terminal to know how to watch it to remove the tzupdateFlag.rtmt file. Any help with that is much appreciated as well. Thanks!

    ReplyDelete
  6. HI, I've verified that there is a blank ZoneInfoMappings file in lib/jre/zi but when I run RTMT now after saying yes to update the timezones, it just gets stuck on the loading page after I log in. It never gets past that. Any ideas? I'm running JRE 8 and El Capitan.

    Thanks.

    ReplyDelete
    Replies
    1. What happens if you say "no" when prompted to update timezones?

      -Bill

      Delete
  7. Another work-around I found for the timezone and NoSuchFieldError is to delete jdk 8 and install the last version of jdk 7 which I found on the archive page at http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html#jdk-7u80-oth-JPR
    You'll need to create a free Oracle account if you don't already have one to access this.
    On first run of rtmt after that, just need to run as root (sudo ./run.sh) once to update the client side timezone and then it all works.

    ReplyDelete
  8. Appreciate the information greatly. I was trying install similar scenario except RTMT for UCCX 9.02 on OSX 10.11.5 but did not get very far. I did install the version 8 SDK:

    GS-MacBook:Downloads gstarr$ java -version
    java version "1.8.0_91"
    Java(TM) SE Runtime Environment (build 1.8.0_91-b14)
    Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode)

    Following your guidelines, the installation stopped with the following error lines:

    Launching installer...

    ./CcmServRtmtPlugin.bin: line 2506: /tmp/install.dir.10467/Linux/resource/jre/bin/java: cannot execute binary file
    ./CcmServRtmtPlugin.bin: line 2506: /tmp/install.dir.10467/Linux/resource/jre/bin/java: Undefined error: 0

    ReplyDelete
  9. You rock. Thanks!

    ReplyDelete