0

Is it possible to compose my launchd.plist file so that an embedded expression is evaluated and not treated as a literal value? And, if so, how?

I have a ~/Library/LaunchAgents/setenv.JAVA_HOME.plist file which contains a /bin/launchctl call as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>setenv.JAVA_HOME</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/launchctl</string>
        <string>setenv</string>
        <string>JAVA_HOME</string>
        <string>$(/usr/libexec/java_home -v1.8)</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>ServiceIPC</key>
    <false/>
</dict>
</plist>

Problem is, the $(/usr/libexec/java_home -v1.8) expression is not evaluated and instead the JAVA_HOME environment variable is assigned the literal value $(/usr/libexec/java_home -v1.8).

I asked this question in Stack Overflow last week but have had so few views I'm guessing that that's not the place for it.

1

Got an answer in the original Stack Overflow question, Is it possible to evaluate an expression in launchd's ProgramArguments array?

It is possible by means of this bash command:

/bin/bash -c '/bin/launchctl setenv JAVA_HOME $(/usr/libexec/java_home -v1.8)'

The plist file you want is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test.so</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>/bin/launchctl setenv JAVA_HOME $(/usr/libexec/java_home -v1.8)</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>ServiceIPC</key>
    <false/>
</dict>
</plist>
  • 1
    this doesn't work for me – klanomath Feb 1 '16 at 18:53
  • klanomath, what is the value of the JAVA_HOME environment variable on your machine after the above file is loaded on login? i.e. what gets printed in Terminal when you run this command: launchctl getenv JAVA_HOME? – Adil Hussain Feb 2 '16 at 10:10
0

Though this is better suited as a comment it's much to long so I made it an answer:

Specs:

  • OS X 10.10.5
  • JDKs 1.8.0_72 and 1.7.0_80 installed (for testing purposes)

Using two different plists test.so.global installed to /Library/LaunchDaemons with the content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test.so.global</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>/bin/launchctl setenv JAVA_HOME $(/usr/libexec/java_home -v 1.7)</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

and test.so.user installed to ~/Library/LaunchAgents with the content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test.so.user</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/bash</string>
        <string>-c</string>
        <string>/bin/launchctl setenv JAVA_HOME $(/usr/libexec/java_home -v 1.8)</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

and both loaded I get the following results:

host:~ user$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home
host:~ user$ launchctl getenv JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home
host:~ user$ sudo launchctl getenv JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home

Only loading test.so.global yields:

host:~ user$ echo $JAVA_HOME
    #empty line
host:~ user$ launchctl getenv JAVA_HOME
host:~ user$ sudo launchctl getenv JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home

Only loading test.so.user yields:

host:~ user$ echo $JAVA_HOME
    #empty line
host:~ user$ launchctl getenv JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_72.jdk/Contents/Home
host:~ user$ sudo launchctl getenv JAVA_HOME

So depending on how/where you want to set JAVA_HOME use either both or one of the two plists.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .