Notes on Linux's alternatives Feature Typically, when there are multiple programs installed that do the same thing, the "thing" in /usr/bin is a link into /etc/alternatives, which is a link to your chosen best "thing". For example, /usr/sbin/sendmail is a link to /etc/alternatives/mta, where /etc/alternatives/mta is a link to either /usr/sbin/sendmail.sendmail or presuming you have postfix installed, /usr/sbin/sendmail.postfix There are other alternatives besides sendmail & postfix. A ls of different default PATH directories, finds these links into /etc/alternatives /usr/bin/cancel -> /etc/alternatives/print-cancel /usr/bin/jar -> /etc/alternatives/jar /usr/bin/java -> /etc/alternatives/java /usr/bin/javac -> /etc/alternatives/javac /usr/bin/lp -> /etc/alternatives/print-lp /usr/bin/lpq -> /etc/alternatives/print-lpq /usr/bin/lpr -> /etc/alternatives/print /usr/bin/lprm -> /etc/alternatives/print-lprm /usr/bin/lpstat -> /etc/alternatives/print-lpstat /usr/bin/mailq -> /etc/alternatives/mta-mailq /usr/bin/newaliases -> /etc/alternatives/mta-newaliases /usr/bin/rmail -> /etc/alternatives/mta-rmail /usr/bin/rmic -> /etc/alternatives/rmic /usr/bin/rmiregistry -> /etc/alternatives/rmiregistry /usr/sbin/lpc -> /etc/alternatives/print-lpc /usr/sbin/sendmail -> /etc/alternatives/mta You can also ls -l /etc/alternatives to see what's what. There's also some config files in the /var/lib/alternatives directory, but I don't understand the format of them. ----------------------------------------------------------------------------- You can use the alternatives command to switch between different options. How do you know what the different options are? # alternatives --display mta mta - status is manual. link currently points to /usr/sbin/sendmail.sendmail /usr/sbin/sendmail.sendmail - priority 90 slave mta-mailq: /usr/bin/mailq.sendmail slave mta-newaliases: /usr/bin/newaliases.sendmail slave mta-rmail: /usr/bin/rmail.sendmail slave mta-sendmail: /usr/lib/sendmail.sendmail slave mta-pam: /etc/pam.d/smtp.sendmail slave mta-mailqman: /usr/share/man/man1/mailq.sendmail.1.gz slave mta-newaliasesman: /usr/share/man/man1/newaliases.sendmail.1.gz slave mta-aliasesman: /usr/share/man/man5/aliases.sendmail.5.gz Current `best' version is /usr/sbin/sendmail.sendmail. The output is a bit confusing 'cause the sendmail stuff has 9 different alternatives, all grouped under this "mta" umbrella, and the output differs depending on whether you have postfix installed or not. With postfix, you get this set of lower-priority lines, /usr/sbin/sendmail.postfix - priority 30 slave mta-pam: /etc/pam.d/smtp.postfix slave mta-mailq: /usr/bin/mailq.postfix slave mta-newaliases: /usr/bin/newaliases.postfix slave mta-rmail: /usr/bin/rmail.postfix slave mta-sendmail: (null) slave mta-mailqman: /usr/share/man/man1/mailq.postfix.1.gz slave mta-newaliasesman: /usr/share/man/man1/newaliases.postfix.1.gz slave mta-aliasesman: /usr/share/man/man5/aliases.postfix.5.gz Current `best' version is /usr/sbin/sendmail.sendmail. ----------------------------------------------------------------------------- The problem I had today was getting some sane alternative defined for java. I have these versions of Java installed on agam, IBMJava2 at /opt/IBMJava2-141/bin/javac To use: /opt/IBMJava2-141/bin/javac Hello.java ==> Hello.class To run: /opt/IBMJava2-141/bin/java Hello ==> Prints Hello World WebSphere at /opt/WebSphere/AppServer/java/bin/javac To use: /opt/WebSphere/AppServer/java/bin/javac Hello.java ==> Infinite Loop but /opt/WebSphere/AppServer/java/bin/java WILL run the Hello.class file from the IBMJava2 compile ok. Lest you get confused (like I did), the below are all NOT normal Java compilers. gcc-java libgcj - This is a run-time environment for Java. EG gij Hello works fine. libgcj-devel - This provides libraries, but no javac. MQSeriesJava gcc-java-ssa libgcj-ssa libgcj-ssa-devel libgcj-ssa libgcj-ssa-devel And to confuse things even more, there is this dummy javac link at /usr/bin/javac -> /etc/alternatives/javac where that points to /usr/share/java/libgcj-java-placeholder.sh which is owned by the libgcj package, but all that is, is (as the name implies), a placeholder. Installing either the IBMJava2 or WebSphere Java compilers, doesn't add /usr/bin/javac or change any "alternative" javac thingy. So what am I suppose to do? Define one or both of these javac's to the alternatives software, so I can switch to it? There are hints how to do this on the web. You need to first define the alternative, then switch to it. Use rpm -q --scripts sendmail to see how to do both. IE /usr/sbin/alternatives --install /usr/sbin/sendmail mta /usr/sbin/sendmail.sendmail 90 \ --slave /usr/bin/mailq mta-mailq /usr/bin/mailq.sendmail \ --slave /usr/bin/newaliases mta-newaliases /usr/bin/newaliases.sendmail \ --slave /usr/bin/rmail mta-rmail /usr/bin/rmail.sendmail \ --slave /usr/lib/sendmail mta-sendmail /usr/lib/sendmail.sendmail \ --slave /etc/pam.d/smtp mta-pam /etc/pam.d/smtp.sendmail \ --slave 3 more slave definitions ... --initscript sendmail and then, /usr/sbin/alternatives --set mta /usr/sbin/sendmail.sendmail So how does this apply for this Java stuff? In general, a Java developer uses the following Java components: jar, java, javac, javadoc, javah, javap, jdb & keytool Perhaps something like ... Ah, wait! I can do a rpm -q --scripts libgcj and see what/how libgcj defined this stupid placeholder alternative. It was with /usr/sbin/alternatives --install /usr/bin/java java /usr/share/java/libgcj-java-placeholder.sh 100 \ --slave /usr/bin/rmiregistry rmiregistry /usr/bin/grmiregistry \ --slave /usr/share/man/man1/rmiregistry.1.gz rmiregistry.1.gz /usr/share/man/man1/grmiregistry.1.gz and /usr/sbin/alternatives --install /usr/bin/javac javac /usr/share/java/libgcj-java-placeholder.sh 100 \ --slave /usr/bin/jar jar /usr/bin/gjar \ --slave /usr/bin/rmic rmic /usr/bin/grmic \ --slave /usr/share/man/man1/jar.1.gz jar.1.gz /usr/share/man/man1/gjar.1.gz \ --slave /usr/share/man/man1/rmic.1.gz rmic.1.gz /usr/share/man/man1/grmic.1.gz So for the IBM Java, I could do alternatives --install /usr/bin/java java /opt/IBMJava2-141/jre/bin/java 110 \ --slave /usr/bin/rmiregistry rmiregistry /opt/IBMJava2-141/jre/bin/rmiregistry # There is no rmiregistry man page specific to IBM's Java Yes! And since the priority is 110 (greater than that stupid placeholder 100), this command even updates the /etc/alternatives/java link to /opt/IBMJava2-141/jre/bin/java So you would expect /usr/bin/java to work, right? No! As I saw in a 11-28-2002 web post (see near the bottom of http://www-106.ibm.com/developerworks/forums/dw_forum.jsp?forum=190&cat=10), IBM's java works if you call it directly, and even if from a link, but not from a link to a link. So now /opt/IBMJava2-141/jre/bin/java -version works and /etc/alternatives/java -version works, but /usr/bin/java -version fails with JVM not found: libjvm.so - libjvm.so Apparently, the java binary is looking all around from where it was called for libjvm.so, hoping to find it in ../jre/bin or ../bin, but working from /etc/alternative/java, this results in /etc/jre/bin and /etc/bin, which don't exist, so it doesn't find it. Isn't this great? To remove, alternatives --remove java /opt/IBMJava2-141/jre/bin/java and alternatives --install /usr/bin/javac javac /opt/IBMJava2-141/bin/javac 110 \ --slave /usr/bin/jar jar /opt/IBMJava2-141/bin/jar \ --slave /usr/bin/rmic rmic /opt/IBMJava2-141/bin/rmic # Again, there are no man pages Let's try it for WebSphere java, alternatives --install /usr/bin/java java /opt/WebSphere/AppServer/java/bin/java 120 \ --slave /usr/bin/rmiregistry rmiregistry /opt/WebSphere/AppServer/java/bin/rmiregistry Yes! java -version is the same as /opt/WebSphere/AppServer/java/bin/java -version and alternatives --install /usr/bin/javac javac /opt/WebSphere/AppServer/java/bin/javac 120 \ --slave /usr/bin/jar jar /opt/WebSphere/AppServer/java/bin/jar \ --slave /usr/bin/rmic rmic /opt/WebSphere/AppServer/java/bin/rmic but I really should add all the other javac tools (javadoc, javah, javap, jdb ...). I wound up removing these with alternatives --remove java /opt/WebSphere/AppServer/java/bin/java & alternatives --remove javac /opt/WebSphere/AppServer/java/bin/javac because I found a replacement for the IBMJava2 packages (see my support notes) and those worked well with the alternatives stuff. What I was doing to get the WebSphere java pieces to work with the alternatives command is correct, but I didn't bother. ================================================================================