Infrastructure at your Service

Morgan Patou

WebLogic – JAVA_HOME in WebLogic, a nightmare?

Everybody knows Java but not everybody loves Java. With everything Oracle is currently doing regarding Java, I can’t say I’m blaming them… But that’s not the topic of this blog! hurrah. Well actually I’m not sure the topic of this blog is much better since I will talk about the management of the JAVA_HOME environment variable with WebLogic and more specifically a very simple WebLogic Server in standalone, nothing more. I always wanted to write a blog about how to properly upgrade Java when using WebLogic so I thought about writing this blog first, as an introduction.

Before going deeply into how WebLogic is managing the JAVA_HOME (and therefore how it manages which Java version is used), in case you will be wondering below, these are some possible values for JAVA_VENDOR: Oracle, HP, IBM, Sun. I assume most people aren’t using this environment variable, they are just using JAVA_HOME and expect it to be working. Let’s see what WebLogic thinks about that…

 

I. JAVA_HOME in WLS 12.1.3

I didn’t check for all versions since it’s a quite lengthy and boring process, but I believe this section applies to all 12.1.x versions. In all sections below, ${MW_HOME} is the same as ${ORACLE_HOME} and ${WL_HOME} is ${ORACLE_HOME}/wlserver.

If you want to start a NodeManager, this is what WebLogic 12.1.3 will do in regard to the JAVA_HOME variable:

  • execute ${DOMAIN_HOME}/bin/startNodeManager.sh
    • execute ${WL_HOME}/server/bin/startNodeManager.sh
      • source ${MW_HOME}/oracle_common/common/bin/commEnv.sh ~~> If the environment variable JAVA_HOME is set, that’s good… But if JAVA_VENDOR isn’t set as well, then your JAVA_HOME isn’t used and instead it uses a hardcoded value set in this file directly. If the new JAVA_HOME’s folder (It specifically checks if it’s a FOLDER !!!) doesn’t exist, then it takes the environment variable JAVA_HOME that you defined but if the folder exists, it keeps the JAVA_HOME with the hardcoded value.

I believe this was done to hide the misery that it’s to handle JAVA_HOME in WebLogic… Basically if you upgraded your Java and replaced the JAVA_HOME environment variable without touching the WebLogic files, WebLogic would try to use the old Java and if the folder isn’t there anymore because you removed it, then it would use the value coming from your JAVA_HOME… Why would they do that? Don’t ask me.

 

If you want to start a Managed Server (it’s the same thing for the AdminServer, except the first line), this is what WebLogic 12.1.3 will do in regard to the JAVA_HOME variable:

  • execute ${DOMAIN_HOME}/bin/startManagedWebLogic.sh
    • execute ${DOMAIN_HOME}/bin/startWebLogic.sh
      • source ${DOMAIN_HOME}/bin/setDomainEnv.sh ~~> It doesn’t care if JAVA_HOME is set, it overwrites it. The value will depend on VM_TYPE and JAVA_VENDOR but it overwrites it using the hardcoded value from this file directly. At this point, JAVA_HOME is set and JAVA_VENDOR is overwritten, except if VM_TYPE=JRockit in which case JAVA_HOME is “@DEFAULT_BEA_JAVA_HOME” and JAVA_VENDOR isn’t set…
        • source ${WL_HOME}/common/bin/commEnv.sh
          • source ${MW_HOME}/oracle_common/common/bin/commEnv.sh ~~> Same script as for the NodeManager, except that this time, JAVA_HOME was overwritten by the setDomainEnv.sh script already… So, if JAVA_HOME OR JAVA_VENDOR isn’t set, then JAVA_HOME is again overwritten by yet another hardcoded value…
        • source ${DOMAIN_HOME}/bin/setStartupEnv.sh
        • source ${DOMAIN_HOME}/bin/setUserOverrides.sh

Summary: It’s a nightmare isn’t it? If you want to be sure that your environment variable JAVA_HOME is used in the end without being overwritten, then… Good luck because that’s not possible. For the NodeManager, it would be possible since you just need to define both JAVA_HOME and JAVA_VENDOR (or make sure you remove any old JDK from the FileSystem so it falls back to your JAVA_HOME) but for the Managed Servers, it’s not possible. Well actually it would be possible by setting your JAVA_HOME variable into the “${DOMAIN_HOME}/bin/setUserOverrides.sh” file… Since this file is loaded at the very end, it would use your values but please don’t do that, it’s so ugly!

You think that’s complicated? Please read below, there is more.

 

II. JAVA_HOME in WLS 12.2.1.2

In WLS 12.2, Oracle changed the way the JAVA_HOME is handled for the NodeManager and for the Managed Servers by introducing several things:

  • A new script is used to set the Java Home for the NodeManager: {DOMAIN_HOME}/bin/setNMJavaHome.sh
  • Two new scripts are used to set the environment: the script ${MW_HOME}/oracle_common/common/bin/commEnv.sh now doesn’t contain anything anymore but instead, it loads ${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh as well as ${MW_HOME}/oracle_common/common/bin/commExtEnv.sh for both the NodeManager and the Managed Servers

 

If you want to start a NodeManager, this is what WebLogic 12.2.1.2 will do in regard to the JAVA_HOME variable:

  • execute ${DOMAIN_HOME}/bin/startNodeManager.sh
    • source ${DOMAIN_HOME}/bin/setNMJavaHome.sh ~~> It doesn’t care if JAVA_HOME is set, it overwrites it. The value will depend on VM_TYPE and JAVA_VENDOR but it overwrites it using the hardcoded value from this file directly. At this point, JAVA_HOME is set and JAVA_VENDOR is overwritten, except if VM_TYPE=JRockit in which case JAVA_HOME is empty and JAVA_VENDOR isn’t set…
    • execute ${WL_HOME}/server/bin/startNodeManager.sh
      • source ${MW_HOME}/oracle_common/common/bin/commEnv.sh
        • source ${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh ~~> Different script but same piece of code as for the NodeManager in WLS 12.1.3, except that this time, JAVA_HOME was overwritten by the setNMJavaHome.sh script already… So, if JAVA_HOME OR JAVA_VENDOR isn’t set, then JAVA_HOME is again overwritten by yet another hardcoded value…
        • source ${MW_HOME}/oracle_common/common/bin/commExtEnv.sh

 

If you want to start a Managed Server, this is what WebLogic 12.2.1.2 will do in regard to the JAVA_HOME variable:

  • execute ${DOMAIN_HOME}/bin/startManagedWebLogic.sh
    • execute ${DOMAIN_HOME}/bin/startWebLogic.sh
      • source ${DOMAIN_HOME}/bin/setDomainEnv.sh ~~> It doesn’t care if JAVA_HOME is set, it overwrites it. The value will depend on VM_TYPE and JAVA_VENDOR but it overwrites it using the hardcoded value from this file directly. At this point, JAVA_HOME is set and JAVA_VENDOR is overwritten, except if VM_TYPE=JRockit in which case JAVA_HOME is “@DEFAULT_BEA_JAVA_HOME” and JAVA_VENDOR isn’t set…
        • source ${MW_HOME}/oracle_common/common/bin/commEnv.sh
          • source ${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh ~~> Same script as for the NodeManager, except that this time, JAVA_HOME was overwritten by the setDomainEnv.sh script already… So, if JAVA_HOME OR JAVA_VENDOR isn’t set, then JAVA_HOME is again overwritten by yet another hardcoded value…
          • source ${MW_HOME}/oracle_common/common/bin/commExtEnv.sh
        • source ${DOMAIN_HOME}/bin/setStartupEnv.sh
        • source ${DOMAIN_HOME}/bin/setUserOverrides.sh

 

III. JAVA_HOME in WLS 12.2.1.3

In WLS 12.2.1.3, Oracle changed again the way the JAVA_HOME is handled for the NodeManager and for the Managed Servers by introducing one more thing: instead of hardcoding the JAVA_HOME in ${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh, it now retrieve the value using a script (${MW_HOME}/oui/bin/getProperty.sh) that read a specific file (${MW_HOME}/oui/.globalEnv.properties).

If you want to start a NodeManager, this is what WebLogic 12.2.1.3 will do in regard to the JAVA_HOME variable:

  • execute ${DOMAIN_HOME}/bin/startNodeManager.sh
    • source ${DOMAIN_HOME}/bin/setNMJavaHome.sh ~~> Same script as for the NodeManager in WLS 12.2.1.2
    • execute ${WL_HOME}/server/bin/startNodeManager.sh
      • source ${MW_HOME}/oracle_common/common/bin/commEnv.sh
        • source ${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh ~~> (Almost) Same script as for the NodeManager in WLS 12.2.1.2, except that this time, JAVA_HOME is again overwritten by retrieving properties value using the new script
          • execute ${MW_HOME}/oui/bin/getProperty.sh JAVA_HOME
            • read ${MW_HOME}/oui/.globalEnv.properties ~~> Always overwrite JAVA_HOME with the hardcoded value
        • source ${MW_HOME}/oracle_common/common/bin/commExtEnv.sh

 

If you want to start a Managed Server, this is what WebLogic 12.2.1.3 will do in regard to the JAVA_HOME variable:

  • execute ${DOMAIN_HOME}/bin/startManagedWebLogic.sh
    • execute ${DOMAIN_HOME}/bin/startWebLogic.sh
      • source ${DOMAIN_HOME}/bin/setDomainEnv.sh ~~> Same script as for the Managed Servers in WLS 12.2.1.2
        • source ${MW_HOME}/oracle_common/common/bin/commEnv.sh
          • source ${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh ~~> (Almost) Same script as for the Managed Servers in WLS 12.2.1.2, except that this time, JAVA_HOME is again overwritten by retrieving properties value using the new script
            • execute ${MW_HOME}/oui/bin/getProperty.sh JAVA_HOME
              • read ${MW_HOME}/oui/.globalEnv.properties ~~> Always overwrite JAVA_HOME with the hardcoded value
          • source ${MW_HOME}/oracle_common/common/bin/commExtEnv.sh
        • source ${DOMAIN_HOME}/bin/setStartupEnv.sh
        • source ${DOMAIN_HOME}/bin/setUserOverrides.sh
        • source ${DOMAIN_HOME}/bin/setUserOverridesLate.sh

 

Easy right? Joke aside, even if it’s a huge mess, with WLS 12.2.1.3, you now have the file “${MW_HOME}/oui/.globalEnv.properties” which is used by both the NodeManager as well as the Admin/Managed Servers and therefore if you overwrite the value in this file, you would think that you are good to go right? Well… “Why would it be so easy?”, that’s probably what Oracle thought when they were thinking about how they should handle the JAVA_HOME internally ;).

Instead of going top to bottom, let’s go the other way around. Let’s say that you updated the value of JAVA_HOME inside the file “${MW_HOME}/oui/.globalEnv.properties”. This file is read using the “${MW_HOME}/oui/bin/getProperty.sh” script which is executed by “${MW_HOME}/oracle_common/common/bin/commBaseEnv.sh”. To execute the getProperty.sh, you need either the JAVA_HOME or the JAVA_VENDOR to be not set or empty.

Before the commBaseEnv.sh script, the only one that contains references to JAVA_HOME or JAVA_VENDOR is:

  • For the NodeManager: ${DOMAIN_HOME}/bin/setNMJavaHome.sh
    • JAVA_HOME can be empty only if VM_TYPE=JRockit, otherwise it’s always overwritten with the hardcoded values
    • JAVA_VENDOR can be empty only if VM_TYPE=JRockit, otherwise it’s always overwritten with “Oracle”
    • Conclusion: To be able to load the value from “${MW_HOME}/oui/.globalEnv.properties”, JAVA_HOME or JAVA_VENDOR needs to be empty so you need to use VM_TYPE=JRockit if you want to use this new “feature” added in WLS 12.2.1.3… And obviously, if your aren’t using a JRockit VM (which, by the way, doesn’t exist anymore: latest stable release was 7 years ago…), then the NodeManager won’t start so good luck trying to use this “${MW_HOME}/oui/.globalEnv.properties” file because it’s impossible ;).
  • For the Managed Servers: ${DOMAIN_HOME}/bin/setDomainEnv.sh
    • JAVA_HOME cannot be empty or not set because of the hardcoded values in this file and even if VM_TYPE=JRockit, then JAVA_HOME is set to “@DEFAULT_BEA_JAVA_HOME”
    • JAVA_VENDOR can be empty only if VM_TYPE=JRockit, otherwise it’s always overwritten with “Oracle”
    • Conclusion: To be able to load the value from “${MW_HOME}/oui/.globalEnv.properties”, JAVA_VENDOR needs to be empty so you need to use VM_TYPE=JRockit… Same conclusion as for the NodeManager, it’s not possible.

So, why did they introduce this new file in WLS 12.2.1.3? Well I can only hope that it is used somewhere! One thing is certain, it’s not for the NodeManager, AdminServer or Managed Servers (there is not much left… :D). If you are aware of anything that would make some use of that, don’t hesitate to share!

So, in summary, WebLogic basically doesn’t care if you set a JAVA_HOME environment variable, it will anyway just use its hardcoded values, contrary to most Application Servers which trusts the people installing/configuring them to set the JAVA_HOME to the expected value. In a future blog, I will talk about the upgrade process of Java in the scope of a WebLogic Server, to make it smoother (well, as much as technically possible… ;)).

 

2 Comments

  • Evgeniy Morozov says:

    Hi!

    I also found that in our OBIEE deployment a file setHomeDirs.cmd in oracle_common also used for setting path to Java. I think it’s application dependend so other app may have another “set environment” script which adds to overall confusion 🙂

    • Morgan Patou says:

      Hi,

      Indeed what I talked about what just a very simple standalone WebLogic Server. If you have another product that rely on it to run, that’s another layer of complexity on top of it which might therefore add even more files to just configure a simple “JAVA_HOME”, you are absolutely right.

      I don’t know much about OBIEE but the setHomeDirs.sh (or .cmd) do come with the standalone WebLogic Server (${MW_HOME}/oracle_common/common/bin/setHomeDirs.sh). I might be wrong but as far as I know, it is not used to know which JVM should be used to start the WebLogic Server, however, it is used indeed for OPatch and some other internal things like WLST execution, aso…

      Regards,
      Morgan

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Morgan Patou
Morgan Patou

Technology Leader ECM & Senior Consultant