This question already has an answer here:
Why cant I run apt install on mac?
(1 answer)
Closed 5 months ago.
I'm trying to do the command sudo apt install git nodejs npm curl but I keep getting an error message that I don't have java installed, even though I do. I've even installed the latest jdk on their website but still get this issue. For reference, I'm using a mac.
sh-3.2$ java -version
java version "1.8.0_341"
Java(TM) SE Runtime Environment (build 1.8.0_341-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.341-b10, mixed mode)
It looks like you're trying to use the APT tool to install software. This is the standard software package management tool for several Linux distributions, but is not commonly used on macOS.
The apt command that ships with macOS is a stub for the deprecated Annotation Processing Tool that used to be part of the Java SE Development Kit (JDK). macOS ships with binaries corresponding to the ones provided with JDK distributions. These built-in command attempt to dispatch to the corresponding tool in the currently installed JDK, or prints an error if this can't be done. In this case, the apt tool was removed from JDK 8 (aka 1.8) and later. It can only be found by installing JDK 7 or earlier.
However, solving this won't solve your overall problem, because this is a completely different tool that happens to share the same command name, but has nothing to do with installing software packages.
If you're following instructions for installing software, be sure you're referring to ones written for macOS and not Linux. While there are some similarities between these operating systems, there are also many differences, particularly in the standard command line tools.
If you don't have existing instructions to follow, consider trying Homebrew to install these packages on macOS. It's popular, well-supported and capable of installing all of these packages.
On the other hand, if you really are intending to use the APT package manager on macOS (for example, via the Fink project), you'll need to ensure that you've correctly set up the PATH environment variable so that the installed apt command is found before the /usr/bin/apt command that ships with macOS.
I have two Ubuntu 20.04 servers, Alpha and Beta, both with Tomcat 9 installed from the standard repo. In principle, they should be virtually identical, but I've found a discrepancy in which version of Java each uses that I can't find the origin of.
On server Alpha, both the ps process listing for Tomcat and systemctl status tomcat9.service show that its Java binary is /usr/lib/jvm/java-8-openjdk-amd64/bin/java. On server Beta, the same commands show that Tomcat's Java binary is /usr/lib/jvm/default-java/bin/java, which is a symlink to /usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java.
Thus, server Alpha uses Java 8, while server Beta uses Java 11. They should be identical, yet something is clearly different.
The obvious question at this point is, how does Tomcat determine which version of Java to use?
1) Documentation
I cannot find the answer to this question in the Tomcat configuration documentation, and there are no other top-level topics in the documentation that seem relevant to this question.
2) Stack Overflow
This Stack Overflow question is the best I can find on the site, and it doesn't have any useful answers for an Ubuntu system; /etc/sysconfig/tomcat{N} is mentioned in one answer, but it does not exist on either server, while /etc/default/tomcat{N} exists on both but does not contain any parameters relating to Java version.
3) Standard config files
I have also checked the main Tomcat config file /var/lib/tomcat9/conf/server.xml and the Tomcat systemd service file /lib/systemd/system/tomcat9.service, but neither contain any parameters relating to Java version. Both servers have a service file override /etc/systemd/system/tomcat9.service.d/override.conf, but since I wrote that myself, I'm certain it doesn't set the version of Java used.
4) setenv.sh
Tomcat's /usr/share/tomcat9/bin/catalina.sh file mentions a JAVA_HOME environment variable, which I have to assume is what I'm looking for. That file appears to expect this variable to be set when it sources one of two files, $CATALINA_BASE/bin/setenv.sh or $CATALINA_HOME/bin/setenv.sh. Neither of these files (or bin/ directories, even) exist on either server, so this can't explain the difference.
That's all I can figure out. The question is:
In the absence of explicit user configuration, what determines what Java version Tomcat uses? This information must be stored in one of the files in Tomcat's installation, but I have no way of knowing which one.
EDIT
As #Emerson Pardo suggested, the two instances of Ubuntu 20.04 did have different default Java versions. After changing Beta's to use Java 8 using the Debian/Ubuntu update-alternatives program and restarting Tomcat, however, the problem outlined above is unchanged. Tomcat continues to use
/usr/lib/jvm/default-java/bin/java -> /usr/lib/jvm/java-1.11.0-openjdk-amd64/bin/java
on Beta.
On derivatives of Debian 10, such as Ubuntu 20.04, Tomcat is started through a wrapper script located in /usr/libexec/tomcat9/tomcat-start.sh. If you don't set JAVA_HOME yourself a heuristic procedure is performed in /usr/libexec/tomcat9/tomcat-locate-java.sh:
# This function sets the variable JDK_DIRS
find_jdks()
{
for java_version in 11 10 9 8
do
for jvmdir in /usr/lib/jvm/java-${java_version}-openjdk-* \
/usr/lib/jvm/jdk-${java_version}-oracle-* \
/usr/lib/jvm/jre-${java_version}-oracle-* \
/usr/lib/jvm/java-${java_version}-oracle \
/usr/lib/jvm/oracle-java${java_version}-jdk-* \
/usr/lib/jvm/oracle-java${java_version}-jre-*
do
if [ -d "${jvmdir}" ]
then
JDK_DIRS="${JDK_DIRS} ${jvmdir}"
fi
done
done
}
# The first existing directory is used for JAVA_HOME
JDK_DIRS="/usr/lib/jvm/default-java"
find_jdks
# Look for the right JVM to use
for jdir in $JDK_DIRS; do
if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
JAVA_HOME="$jdir"
fi
done
export JAVA_HOME
Therefore:
if /usr/lib/jvm/default-java exists it is chosen,
otherwise the highest (up to 11) version of Java is used.
Generally, Ubuntu chooses what Java it will be used by default. You can find it like this:
$ which java
/usr/bin/java
$/usr/bin/java --version
openjdk 11.0.11 2021-04-20
OpenJDK Runtime Environment (build 11.0.11+9-Ubuntu-0ubuntu2.18.04)
OpenJDK 64-Bit Server VM (build 11.0.11+9-Ubuntu-0ubuntu2.18.04, mixed mode, sharing)
You can also check the alternatives available in your system using:
$ update-java-alternatives -l
which will list all java installed.
To choose a specific version you can use:
$ sudo update-alternatives --config java
Situation
The problem I have encountered is that there will be no sound output from running my *.jar file. I will start it with java -jar cgoban.jar and it works fine except there is no sound.
Possible Solutions
There is a workaround for this problem discussed here: https://senseis.xmp.net/?CgobanProblemsAndSolutions.
It says to employ the Java Web Start with
LIBXCB_ALLOW_SLOPPY_LOCK=true padsp javaws http://files.gokgs.com/javaBin/cgoban.jnlp
and use the jlnp file from here: http://files.gokgs.com/javaBin/cgoban.jnlp.
However, since this workaround includes downloading the jar-file on every start this is not an option for me (as I use an offline machine, bandwidth limitations etc.)
A possible solution might be to run (since it works with javaws)
LIBXCB_ALLOW_SLOPPY_LOCK=true padsp java -jar cgoban.jar
but there is still no sound. I don't understand why it works for javaws, but not for java -jar.
Unluckily it did not help to run
java -jar -Dsun.sound.useNewAudioEngine="false" cgoban.jar
But thanks for commenting.
Another possible solution that I attempted was to download and edit above jlnp-file. I don't want to download the jar-file every time the application starts. So maybe it is possible to download the jar-file once and then have the local jlnp-file point to the local copy (instead of the remote jar-file). However, as my programming skills suck, I have not been able to pull this off.
Additional Information
I'm running an Ubuntu machine with Java installed. java -version gives me the following output:
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-8u151-b12-0ubuntu0.16.04.2-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)
An up-to-date version of cgoban.jar for download is available from here:
http://files.gokgs.com/javaBin/cgoban.jar
Does anyone know where I can find a gradle-compatible buildback for Heroku that includes the Oracle Java JDK 1.8?
I'm deploying a reasonably complex spring application and I have a feeling the strange errors are caused by differences between OpenJDK and OracleJDK.
Alternatively, perhaps someone can guide me to forking an existing buildpack and creating my own.
EDIT: It wasn't a JDK issue after all
First of all, this is unlikely to solve your problem. That said...
You can customize the JDK by setting the JDK_URL_1_8 config var like so:
$ heroku config:set JDK_URL_1_8=http://...tar.gz
For Oracle JDK: you must strip the jdk1.8.0_51 dir from the tarball. You can do this by running:
$ tar -xvf jdk-8u51-linux-x64.gz
$ cd jdk1.8.0_51
$ tar -cv -f jdk-8u51-linux-x64.gz .
You should manually download the OracleJDK, edit as per above, and put it in a personal S3 bucket (or some other storage). Then use that URL for your config var.
Be aware that the Oracle JDK is much larger than the OpenJDK (by about 100mb). This will affect your slug size. (The size is mainly due to junk you don't need like GUI stuff and docs).
We have a couple of applications running on Java 5 and would like now to bring in an application based on Java 6. Can both java versions live together under Windows?
Is there any control panel to set the appropriate Java version for different applications, or any other way to set up, what version of Java will be used to run that particular application?
Of course you can use multiple versions of Java under Windows. And different applications can use different Java versions. How is your application started? Usually you will have a batch file where there is something like
java ...
This will search the Java executable using the PATH variable. So if Java 5 is first on the PATH, you will have problems running a Java 6 application. You should then modify the batch file to use a certain Java version e.g. by defining a environment variable JAVA6HOME with the value C:\java\java6 (if Java 6 is installed in this directory) and change the batch file calling
%JAVA6HOME%\bin\java ...
I was appalled at the clumsiness of the CLASSPATH, JAVA_HOME, and PATH ideas, in Windows, to keep track of Java files. I got here, because of multiple JREs, and how to content with it. Without regurgitating information, from a guy much more clever than me, I would rather point to to his article on this issue, which for me, resolves it perfectly.
Article by: Ted Neward: Multiple Java Homes: Giving Java Apps Their Own JRE
With the exponential growth of Java as a server-side development language has come an equivablent
exponential growth in Java development tools, environments, frameworks, and extensions.
Unfortunately, not all of these tools play nicely together under the same Java VM installation. Some
require a Servlet 2.1-compliant environment, some require 2.2. Some only run under JDK 1.2 or above,
some under JDK 1.1 (and no higher). Some require the "com.sun.swing" packages from pre-Swing 1.0
days, others require the "javax.swing" package names.
Worse yet, this problem can be found even within the corporate enterprise, as systems developed using
Java from just six months ago may suddenly "not work" due to the installation of some Java Extension
required by a new (seemingly unrelated) application release. This can complicate deployment of Java
applications across the corporation, and lead customers to wonder precisely why, five years after the
start of the infamous "Installing-this-app-breaks-my-system" woes began with Microsoft's DLL schemes,
we still haven't progressed much beyond that. (In fact, the new .NET initiative actually seeks to solve the
infamous "DLL-Hell" problem just described.)
This paper describes how to configure a Java installation such that a given application receives its own,
private, JRE, allowing multiple Java environments to coexist without driving customers (or system
administrators) insane...
It is absolutely possible to install side-by-side several JRE/JDK versions. Moreover, you don't have to do anything special for that to happen, as Sun is creating a different folder for each (under Program Files).
There is no control panel to check which JRE works for each application. Basically, the JRE that will work would be the first in your PATH environment variable. You can change that, or the JAVA_HOME variable, or create specific cmd/bat files to launch the applications you desire, each with a different JRE in path.
We can install multiple versions of Java Development kits on the same machine using SDKMan.
Some points about SDKMan are as following:
SDKMan is free to use and it is developed by the open source community.
SDKMan is written in bash and it only requires curl and zip/unzip programs to be present on your system.
SDKMan can install around 29 Software Development Kits for the JVM such as Java, Groovy, Scala, Kotlin and Ceylon. Ant, Gradle, Grails, Maven, SBT, Spark, Spring Boot, Vert.x.
We do not need to worry about setting the _HOME and PATH environment variables because SDKMan handles it automatically.
SDKMan can run on any UNIX based platforms such as Mac OSX, Linux, Cygwin, Solaris and FreeBSD and we can install it using following commands:
$ curl -s "https://get.sdkman.io" | bash
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
Because SDKMan is written in bash and only requires curl and zip/unzip to be present on your system. You can install SDKMan on windows as well either by first installing Cygwin or Git Bash for Windows environment and then running above commands.
Command sdk list java will give us a list of java versions which we can install using SDKMan.
Installing Java 8
$ sdk install java 8.0.201-oracle
Installing Java 9
$ sdk install java 9.0.4-open
Installing Java 11
$ sdk install java 11.0.2-open
Uninstalling a Java version
In case you want to uninstall any JDK version e.g., 11.0.2-open you can do that as follows:
$ sdk uninstall java 11.0.2-open
Switching current Java version
If you want to activate one version of JDK for all terminals and applications, you can use the command
sdk default java <your-java_version>
Above commands will also update the PATH and JAVA_HOME variables automatically. You can read more on my article How to Install Multiple Versions of Java on the Same Machine.
It should be possible changing setting the JAVA_HOME environment variable differently for specific applications.
When starting from the command line or from a batch script you can use set JAVA_HOME=C:\...\j2dskXXX to change the JAVA_HOME environment.
It is possible that you also need to change the PATH environment variable to use the correct java binary. To do this you can use set PATH=%JAVA_HOME%\bin;%PATH%.
I use a simple script when starting JMeter with my own java version
setlocal
set JAVA_HOME="c:\java8"
set PATH=%JAVA_HOME%\bin;%PATH%;
java -version
To have a java "portable"
you can use this method here:
https://www.whitebyte.info/programming/java/how-to-install-a-portable-jdk-in-windows-without-admin-rights
Or use links. While it is rather unpleasant to update the PATH in a running environment, it's easy to recreate a link to a new version of JRE/JDK. So:
install different versions of JDK you want to use
create a link to that folder either by junction or by built-in mklink command
set the PATH to the link
If other version of java is to be used, delete the link, create a new one, PATH/JAVA_HOME/hardcoded scripts remain untouched
Invoking Java with "java -version:1.5", etc. should run with the correct version of Java. (Obviously replace 1.5 with the version you want.)
If Java is properly installed on Windows there are paths to the vm for each version stored in the registry which it uses so you don't need to mess about with environment versions on Windows.
If you use Java Web Start (you can start applications from any URL, even the local file system) it will take care of finding the right version for your application.
Using Java Web Start, you can install multiple JRE, then call what you need.
On win, you can make a .bat file:
1- online version:
<your_JRE_version\bin\javaws.exe> -localfile -J-Djnlp.application.href=<the url of .jnlp file.jnlp> -localfile -J "<path_temp_jnlp_file_.jnlp>"
2- launch from cache:
<your_JRE_version\bin\javaws.exe> -localfile -J "<path_of_your_local_jnlp_file.jnlp>"