Check java version during program load - java

I'm looking for a way to check which java version my software is running under.
I'd like to verify during load time my software is running on at least

To get the java version you can use any of these depending on the version you want:
java.specification.version
java.version
java.vm.version
java.runtime.version
However, note that java versions are not equivalent between operative systems. So Java 6 on OSX does not mean the same thing as Java 6 on Windows. So, I would recommend you to also get the OS where the application is running, if you wish to determine if a given feature is available:
System.getProperty("os.name")
As a general guideline, all of this stuff is in the System package. A trick I use is iterate through all the available fields to have an idea of what I can use:
import java.util.Map;
class ShowProperties {
public static void main(String[] args) {
for (Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
System.out.println(e);
}
}
}

Use java.version property to retrieve the jre version.
String javaVersion = System.getProperty("java.version");
if ((!javaVersion.startsWith("1.6")) && (!javaVersion.startsWith("1.7")) && (!javaVersion.startsWith("1.8")) && (!javaVersion.startsWith("1.9")))
{
// error
}

You can use System.getProperty:
System.out.println(System.getProperty("java.version"));
1.7.0_21

java.lang.System.getProperty("java.version")

Related

Java check if program is installed on windows

Is there a way to check if a specific program is installed on Windows using Java?
I'm trying to develop a Java program that automatically creates zip archives by using the code line command from 7-Zip.
So, I would like to check in Java if on my windows OS '7-Zip' is already installed. No check for running apps or if OS is Windows or Linux. I want to get a bool (true/false) if '7-Zip' is installed on Windows.
The library Apache Commons has a class called SystemUtils - full documentation is available at https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SystemUtils.html.
In this library you have the following static boolean properties at your disposal:
SystemUtils.IS_OS_LINUX
SystemUtils.IS_OS_WINDOWS
The unix-like solution would be to simply try to run the program with --version flag (on windows probably the /? or - like in the 7zip case - without any at all) and check whether it fails, or what the return code will be.
Something like:
public boolean is7zipInstalled() {
try {
Process process = Runtime.getRuntime().exec("7zip.exe");
int code = process.waitFor();
return code == 0;
} catch (Exception e) {
return false;
}
}
I assume that you're talking about Windows. As Java is intended to be a platform-independent language and the way how to determine it differs per platform, there's no standard Java API to check that. You can however do it with help of JNI calls on a DLL which crawls the Windows registry. You can then just check if the registry key associated with the software is present in the registry. There's a 3rd party Java API with which you can crawl the Windows registry: jRegistryKey.
Here's an SSCCE with help of jRegistryKey:
package com.stackoverflow.q2439984;
import java.io.File;
import java.util.Iterator;
import ca.beq.util.win32.registry.RegistryKey;
import ca.beq.util.win32.registry.RootKey;
public class Test {
public static void main(String... args) throws Exception {
RegistryKey.initialize(Test.class.getResource("jRegistryKey.dll").getFile());
RegistryKey key = new RegistryKey(RootKey.HKLM, "Software\\Mozilla");
for (Iterator<RegistryKey> subkeys = key.subkeys(); subkeys.hasNext();) {
RegistryKey subkey = subkeys.next();
System.out.println(subkey.getName()); // You need to check here if there's anything which matches "Mozilla FireFox".
}
}
}
If you however intend to have a platformindependent application, then you'll also have to take into account the Linux/UNIX/Mac/Solaris/etc. (in other words: anywhere where Java is able to run) ways to detect whether FF is installed. Else you'll have to distribute it as a Windows-only application and do a System#exit() along with a warning whenever System.getProperty("os.name") is not Windows.
Sorry, I don't know how to detect in other platforms whether FF is installed or not, so don't expect an answer from me for that ;)

Fixing JRE error in Java code and recompiling application

I tried run on Windows 7 some old utility that depends on old JRE version.
I have last Java Runtime Environment 1.7.0_79 installed. When I attepmt to start application, I got an error:
"Sivus requires JRE 1.4 or later to run. You can download JRE
from...etc"
Is there a workaround to resolve/fix this or something of that nature?
Program main executable packed in SFX ZIP archive, I extracted files, and found Java file, which makes the check. There is a code:
public static boolean checkJavaVersion(){
boolean ok = false;
String version = System.getProperty("java.version");
if (version.indexOf("1.1") > -1) {
ok = false;
}
else if (version.indexOf("1.2") > -1) {
ok = false;
}
else if (version.indexOf("1.3") > -1) {
ok = false;
}
else if (version.indexOf("1.4") > -1) {
ok = true;
}
else if (version.indexOf("1.5") > -1) {
ok = true;
}
return ok;
}
public static void main(String[] args) {
boolean DEBUG = false;
try {
// check if JRE is over 1.4
if (checkJavaVersion() == false){
JOptionPane.showMessageDialog(
null,
"SiVuS requires JRE 1.4 (or later) to run.\n"
+"You can download the latest JRE from java.sun.com",
"Java Run Time Environment Error",
JOptionPane.WARNING_MESSAGE);
System.exit(1);
}
How to correct this issue and recompile the application again? Will the application that relies on JRE 1.4 work with current JRE?
An example of how I'm doing patches like this.
Fix code - you can add 1.6, 1.7, 1.8 to checkJavaVersion or remove this check at main method.
Put fixed java file in folder that matches package
Compile java file, for example:
call "C:\Program Files (x86)\Java\jdk1.7.0_79\bin\javac.exe" C:\test\mypackage\MyClass.java -cp C:\test\My.jar -source 1.4 -target 1.4
Get compiled class file and replace old file (backup it first)
First of all, I would recommend not using an old tool whose "provenance" is doubtful. Especially, not as a security scanner. Surely, you can find a tool that is newer, and better supported than this one ...
If you wish to proceed (and take a risk) then one approach would be to modify that class, recompile and rebuild the JAR file, as suggested by #Rustam.
Another approach would be to create a simple wrapper class with a main method that called System.setProperty to tweak the value of the "java.version" property, and then called the real main method.

Java's "os.name" for Windows 10?

In Java, we can see the property value of os.name to know the name of the underlying operating system: System.getProperty("os.name").
For each edition of Windows, it used to return always the exact name of the OS: Windows XP for XP, Windows Vista for Vista, Windows 7 for Seven, Windows 8.1 for 8.1, and so on...
The problem is: I just updated my Windows 8.1 to Windows 10 using the released Microsoft updater, and it seems like this property still remains Windows 8.1:
public class OSTest {
public static void main(String[] args) {
System.out.println(System.getProperty("os.name"));
}
}
How can I create a workaround for this? And, does anyone know if this problem persists if installing a fresh Windows 10 copy - that is, this bug is caused by the Microsoft auto-updater -?
This is a known problem JDK-8066504 that has been fixed in upcoming Java 8 update 60.
The reason is GetVersionEx function has changed its behavior since Windows 8.1.
There are multiple possible workarounds, see MSDN article.
The trivial one is to exec cmd.exe /c ver.
The other is to look at the version information of one of the system files, e.g. kernel32.dll.
This is definitely a known bug. It occurs because the os.name property gets its value from the GetVersionEx in the source code of the Windows API. GetVersionEx however,
may be altered or unavailable for releases after Windows 8.1
As per Microsoft's official website. Instead, we will need to use the IsWindows10OrGreater found in the Version Helper API functions in the versionhelpers.h file. As you probably guessed though, this file is not a Java file, it is written in C. As a result we need to include it in a somewhat roundabout way. It does take quite a bit of work (you need to program in JNI :/) but this tutorial will help you do it. Another solution is shown in this bug log, and does require less effort.
I faced the same issue, used the following workaround:
The cmd command "systeminfo" returns "OS Name:" which is the right name for the OS, wrote the following function for this:
private boolean os2k10Check()
{
try{
Process p = Runtime.getRuntime().exec("systeminfo"); /*Execute cmd command "systeminfo"*/
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true)
{
line = r.readLine();
if (line == null) { break; }
if(line.contains("OS Name:")) /*If output contains OS Name and 2010*/
{
if(line.contains("2010"))
return true;
else
return false;
}
}
}
catch(Exception e)
{System.out.println("Platform Type: os2010check: exception"+e);}
return false;
}
Hm... I don't know if it is a fix of Windows 10(10.0.17134.590) or of Java 8(1.8.0_171-b11 for me), but it is correct now: os.name gives me Windows 10.
Besides, if you don't trust it, you can check os.version. I have 10.0.
(By the way, I see os.arch:amd64. This is of JVM, not of OS. )
You could also use the .contains() method and just check for the "windows"
string maybe along the lines of
if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains(windows version here [xp, 7, 8, etc]))){}
If you need the windows version you could check for all versions and then assume 8.1 or 10 to move around the bug.
if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("xp")){
//code for windows xp }
else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("vista")){
//code for windows vista
else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("7")){
//code for windows 7}
else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("8")){
//code for windows 8}
else if (System.getProperty("os.name").toLowerCase().contains("windows") && System.getProperty("os.name").toLowerCase().contains("8.1")){
//code for both windows 8.1 and 10
}
Now to explain what is going on here:
the if statement is just a conditional to determine the version of windows
The System.getProperty("os.name") returns the name of the os as a string
The .toLowerCase() method makes that returned String lower case
The .contains(String) method checks if the given input string is contained in the String it is being called on
The last statement allows for different code for each os except 8.1 & 10 which would need to be handled as one block :(

The printf method won't work

This is the second time I've tried to use the PrintWriter#printf method, and I get this error message:
The method printf(String, Object[]) in the type PrintStream is not applicable for the argument (String, String)
The code I'm using has two classes.
This is the first class:
class apples4 {
public static void main(String[] args) {
tuna4 tuna4Object = new tuna4("Kelsey");
tuna4Object.saying();
}
}
This is the second class:
public class tuna4 {
private String girlName;
public tuna4(String name) {
girlName=name;
}
public void setName(String name) {
girlName=name;
}
public String getName() {
return girlName;
}
public void saying(){
System.out.printf("Your first girlfriend was %s\n", getName() );
}
}
Check your compliance level...
PrintStream#printf method is available since Java SE 5. Looks like your code is being compiled/evaluated by Java 4 or prior.
Review your JDK installation and/or your IDE settings about how it is compiling/evaluating your code.
By the way, if using Eclipse and Java 8, Eclipse needs a plugin to recognize Java 8 applications, so by default the evaluator will downgrade your project to Java 1.4. This happened to me and I solved it by installing an update in Eclipse Kepler. Eclipse Luna (latest Eclipse version)says that it supports Java 8, but didn't work for me (not sure if I followed the right steps or did something wrong, but went back to Kepler and works fine).
It might sound weird, but you can cast the return value of your getName() method to Object:
System.out.printf("Your first girlfriend was %s\n", (Object) getName());
Or (to create the requested array) even
System.out.printf("Your first girlfriend was %s\n", new Object[] {(Object) getName()} );
could help.
I'm sorry about my previous post saying I had the same problem, I didn't read the "before you post read this" dialog box that says don't do that. Well, after a lot of time looking around for the answer, I figured it out myself. In Preferences->Java->Compiler box, there is a button in the top left corner called "Configure Project Specific Settings...". Click it and either change the compliance level to >= Java 1.5, or turn it off. Boom, fixed.
you might need to change the execution environment if it's not already java SE 1.8
it might be CDC or sth else , so u need to change it to java SE 1.8
details in picture 1.expand ur project then 2.right click on JRE System Library and choose properties finally 3. if the environment is not java SE 1.8 ,change it to become so

Java backward compatibility explanation

I have a java class file. I compiled with JVM 7. which I implemented java 1.7 additions like String switchcase, diamond operator. Now I want to run this .class file on java 1.6 JRE. Will it run?
A simple program using string switchcase As I uninstalled 6. Please try it out and give me answer
import java.util.Scanner;
public class Classing
{
public static void main(String[] args)
{
System.out.println("Enter a month to know who you are");
System.out.println("Jan \n Feb \n Mar \n Apr");
Scanner scan=new Scanner(System.in);
String name=scan.nextLine();
System.out.println(fortune(name.toLowerCase()));
}
public static String fortune(String s)
{
switch(s)
{
case "jan":
return "Good guy";
case "feb":
return "Nice guy";
case "mar":
return "Brave guy";
case "apr":
return "Super guy";
}
return " Month out of option"+s;
}
}
Java 7's switch on Strings compiles down to the same bytecodes which the Java 6 (and earlier) JRE executes. The same is true of the diamond operator. These are compiler features, not runtime features.
So while I've never tried, I would expect that if you compile code which uses these features using the Java 7 compiler, it should still run on the Java 6 JRE. Of course, if you try to compile that code using the Java 6 compiler, all you will get is a syntax error.
If you really want to know try it and see!
Even though this question has an accepted answer, according to http://www.oracle.com/technetwork/java/javase/compatibility-417013.html#binary
The class file version for Java SE 7 is 51, as per the JVM Specification, because of the invokedynamic byte code introduced by JSR 292. Version 51 class files produced by the Java SE 7 compiler cannot be used in Java SE 6.
No it will not. Just because of the simple reason that ,JRE7 features are not available on JRE6.
It wont even compile if you just even copy paste the code which you implemented on 1.7 to new class of 1.6 ,because you used features which was introduced in 1.7 only

Categories

Resources