Goal: check java's version on a machine (I can get this from java -version). Compare it with latest available from java website
I would like to know if there is any way I can check for latest Java releases assuming that I have JRE/JDK installed on a machine.
If I can do this through Java itself, my solution would become platform independent. I could use java.net.URL class to send a request to Java website and get the HTML, however the response would be dynamic as Oracle can change their website and styles and possibly will have maintenance issues in long run.
I have looked at javatester.org, but I would not want it through an applet but through command line (which I can add to a script).
Through javacpl.exe, I can schedule periodic checks, but I would like to do it on demand.
The answer is actually quite simple. http://java.com/en/download/testjava.jsp issues a request to http://java.com/applet/JreCurrentVersion2.txt. That file currently contains a single version number: '1.7.0_11'...which is the latest and greatest, indeed.
Java code example
try (BufferedReader br = new BufferedReader(new InputStreamReader(new URL(
"http://java.com/applet/JreCurrentVersion2.txt").openStream()))) {
String fullVersion = br.readLine();
String version = fullVersion.split("_")[0];
String revision = fullVersion.split("_")[1];
System.out.println("Version " + version + " revision " + revision);
} catch (IOException e) {
// handle properly
}
Update 2014-03-20
Eventhough Java 8 was recently released http://java.com/applet/JreCurrentVersion2.txt currently still returns 1.7.0_51.
Update 2016-07-13
Looks like we need to come back to this every few months... Currently you need to scan http://java.com/en/download/installed8.jsp for a JavaScript variable latest8Version. So, you could run curl -s https://java.com/en/download/installed8.jsp | grep latest8Version.
Update 2018-08-19
http://javadl-esd-secure.oracle.com/update/baseline.version is another hot spot as mentioned in some other answer.
An URL very similar to the now defunct "JreCurrentVersion2.txt":
http://javadl-esd-secure.oracle.com/update/baseline.version
The contents of the link look like this:
1.8.0_111
1.7.0_121
1.6.0_131
1.5.0_99
1.4.2_43
You can easily parse the contents to find the latest JRE versions.
UPDATE: I don't recommend this method because this JRE is the one that has the Ask.com toolbar. You're better off downloading it yourself and distributing it yourself.
The jusched.exe program accesses the following URL to find out what versions are available. I think it's less likely to change because jusched is installed on millions of computers.
https://javadl-esd-secure.oracle.com/update/1.7.0/map-m-1.7.0.xml
Here is a snippet of what it returns for me:
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>
<java-update-map version="1.0">
<mapping>
<version>1.7.0_17</version>
<url>https://javadl-esd-secure.oracle.com/update/1.7.0/au-descriptor-1.7.0_25-b17.xml</url>
</mapping>
<mapping>
<version>1.7.0_21</version>
<url>https://javadl-esd-secure.oracle.com/update/1.7.0/au-descriptor-1.7.0_25-b17.xml</url>
</mapping>
</java-update-map>
To get the actual version that it is pointing to you have to fetch the above URL. Here is another snippet of what this XML looks like:
xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- XML file to be staged anywhere, and pointed to by map.xml file -->
<java-update>
<information version="1.0" xml:lang="en">
<caption>Java Update - Update Available</caption>
<title>Java Update Available</title>
<description>Java 7 Update 25 is ready to install. Installing Java 7 Update 25 might uninstall the latest Java 6 from your system. Click the Install button to update Java now. If you wish to update Java later, click the Later button.</description>
<moreinfo>http://java.com/moreinfolink</moreinfo>
<AlertTitle>Java Update Available</AlertTitle>
<AlertText>A new version of Java is ready to be installed.</AlertText>
<moreinfotxt>More information...</moreinfotxt>
<url>http://javadl.sun.com/webapps/download/GetFile/1.7.0_25-b17/windows-i586/jre-7u25-windows-i586-iftw.exe</url>
<version>1.7.0_25-b17</version>
<post-status>https://nometrics.java.com</post-status>
<cntry-lookup>http://rps-svcs.sun.com/services/countrylookup</cntry-lookup>
<predownload></predownload>
<options>/installmethod=jau FAMILYUPGRADE=1 SPWEB=http://javadl-esd.sun.com/update/1.7.0/sp-1.7.0_25-b17</options>
<urlinfo>24595ec7f861bc67e572f1e4ad3992441335e1a7</urlinfo>
</information>
</java-update>
The version tag contains the full version number.
You could parse the Java SE Downloads page to extract the Java versions.
That way, you get the version of both JDK6 and JDK7, which allows you to test your particular JDK (6 or 7) against the latest Oracle one.
(As opposed to the Free Java Download page, which only lists the JDK7)
Her is a crude script in Go, which you can compile on Windows, Unix, MacOs into a single independent executable, and use within a command line or a script:
package main
import (
"bytes"
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"os/exec"
"regexp"
)
type Jdk struct {
Url string
Ver string
update string
}
func main() {
resp, err := http.Get("http://www.oracle.com/technetwork/java/javase/downloads/index.html")
if err != nil {
fmt.Printf("Error on http Get: %v\n", err)
return
}
bodyb, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Printf("QueriesForOwner: error in ReadAll: %v\n", err)
return
}
br := bytes.NewBuffer(bodyb)
jdkre, err := regexp.Compile(`h3[^\r\n]+(/technetwork/java/javase/downloads/(jdk(?:6|7)(?:u(\d+))?)-downloads-\d+\.html)`)
if err != nil {
fmt.Printf("extract: error in regexp compilation: %v\n", err)
return
}
jdks := jdkre.FindAllSubmatch(br.Bytes(), -1)
jdk7 := Jdk{string(jdks[0][4]), string(jdks[0][5]), string(jdks[0][6])}
jdk6 := Jdk{string(jdks[1][7]), string(jdks[1][8]), string(jdks[1][9])}
fmt.Printf("Jdk7: %v\nJdk6: %v\n", jdk7, jdk6)
jver, err := exec.Command("java", "-version").CombinedOutput()
if err != nil {
fmt.Printf("*ExitError from java -version:", err)
return
}
fmt.Println("JVer: '", string(jver), "'")
jverre, err := regexp.Compile(`1.(\d).\d(?:_(\d+))"`)
jvers := jverre.FindSubmatch(jver)
jj := string(jvers[0])
jv := string(jvers[1])
ju := string(jvers[2])
jdk := jdk6
if jv == "7" {
jdk = jdk7
}
if jdk.update != ju {
fmt.Println("Local JDK *NOT* up-to-date: you have ", jj, ", Oracle has ", jdk.Ver)
} else {
fmt.Println("Local JDK *up-to-date*: you have ", jj, ", equals to Oracle, which has", jdk.Ver)
}
}
Again, this is a crude script, oriented toward JDK, and you would need to adapt it to your specific need, making its output and exit status match what you need for your script.
On my (PC) workstation, it returns:
Jdk7: {/technetwork/java/javase/downloads/jdk7u9-downloads-1859576.html jdk7u9 9}
Jdk6: {/technetwork/java/javase/downloads/jdk6u37-downloads-1859587.html jdk6u37 37}
JVer: ' java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b05)
Java HotSpot(TM) Client VM (build 20.6-b01, mixed mode, sharing)
'
Local JDK *NOT* up-to-date: you have 1.6.0_31" , Oracle has jdk6u37
I don't know what information you are exactly looking for, but you can get some version information using
System.getProperty("java.version");
If this is not what you're looking for, check the other available properties here:
http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#getProperties()
As for the latest available version, I guess you'd have to parse this site manually:
http://java.com/en/download/index.jsp
The latest version is on there, currently it's
Version 7 Update 9
You write that this is not what you want because "Oracle can change their website and styles". However, you want to find out the latest version of Java by accessing their service (website in this case). As long as you're not paying for this, they have no obligation to you, and can change the service whenever they want without your consent. And even when you're a paying customer, the best you can hope for is that they will inform you of upcoming changes, and your maintenance issues will remain.
Remember, it's THEIR service you want to use.
I have solved a similar issue some time ago with this groovy script (disclaimer: is somehow a "toy" script):
#Grapes([
#Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='1.2.1')
])
def slurper = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser())
def url = new URL("http://www.java.com/download/manual.jsp")
def html
url.withReader { reader ->
html = slurper.parse(reader)
}
def lastJava = html.body.div.div.div.strong.text()
println "Last available java version: ${lastJava}"
println "Currently installed java version: ${System.properties["java.version"]}"
It yields something like:
Last available java version:
Version 7 Update 9
Currently installed java version: 1.7.0_07
If you want to avoid maintenance issues due to changes to the page structure, maybe a better option is to search for a line containing "Version x Update y".
To get all system variables
Properties properties = System.getProperties();
System.out.println(properties);
Sample output, this might be different in your system depending on your OS and Java JDK/JRE version.
{
java.runtime.name = Java(TM) SE Runtime Environment,
sun.boot.library.path = C:\Program Files\Java\jdk1.8.0_31\jre\bin,
java.vm.version = 25.31-b07,
java.vm.vendor = Oracle Corporation,
java.vendor.url = http://java.oracle.com/,
path.separator = ;,
idea.launcher.port = 7534,
java.vm.name = Java HotSpot(TM) 64-Bit Server VM,
file.encoding.pkg = sun.io,
user.country = NP,
user.script = ,
sun.java.launcher = SUN_STANDARD,
sun.os.patch.level = ,
java.vm.specification.name = Java Virtual Machine Specification,
user.dir = C:\Users\...\roid,
java.runtime.version = 1.8.0_31-b13,
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment,
java.endorsed.dirs = C:\Program Files\Java\jdk1.8.0_31\jre\lib\endorsed,
os.arch = amd64,
java.io.tmpdir = C:\Windows\TEMP\,
line.separator = ,
java.vm.specification.vendor = Oracle Corporation,
user.variant = ,
os.name = Windows 8.1,
sun.jnu.encoding = Cp1252,
java.library.path = C:\Program...roid,
java.specification.name = Java Platform API Specification,
java.class.version = 52.0,
sun.management.compiler = HotSpot 64-Bit Tiered Compilers,
os.version = 6.3,
user.home = C:\Users\Xxx,
user.timezone = Asia/Kathmandu,
java.awt.printerjob = sun.awt.windows.WPrinterJob,
file.encoding = UTF-8,
idea.launcher.bin.path = C:\Program Files (x86)\xxx\bin,
java.specification.version = 1.8,
java.class.path = C:\Program Files\Java\jdk1.8.0_31\jre\lib\charsets.jar;...,
user.name = Xxx,
java.vm.specification.version = 1.8,
sun.java.command = com.xxxx.ameras,
java.home = C:\Program Files\Java\jdk1.8.0_31\jre,
sun.arch.data.model = 64,
user.language = en,
java.specification.vendor = Oracle Corporation,
awt.toolkit = sun.awt.windows.WToolkit,
java.vm.info = mixed mode,
java.version = 1.8.0_31,
java.ext.dirs = C:\Program Files\Java\jdk1.8.0_31\jre\lib\ext;...,
java.vendor = Oracle Corporation,
file.separator = \,
java.vendor.url.bug = http://bugreport.sun.com/bugreport/,
sun.io.unicode.encoding = UnicodeLittle,
sun.cpu.endian = little,
sun.desktop = windows,
sun.cpu.isalist = amd64
}
Retrive only specific variable
String javaVersion = System.getProperty("java.version");
System.out.println(javaVersion);
Output
1.8.0_31
#MarcelStör's solution no longer works - the version in the file is 1.8.0_51, while the actual latest version is 1.8.0_91/92. If you go to the Java test page in Firefox or Chrome and open the development console you can get the variable latest8Version which currently is 1.8.0_91. This could be wrapped in a Selenium/Firefox solution, but is an incredibly hacky way of getting this information.
System.getProperty("java.vm.specification.version");
System.getProperty("java.version");
Related
On Windows Server 2016, we are trying to connect over JDBC with a Jython script but it is giving following error:
java.lang.ClassNotFoundException: java.lang.ClassNotFoundException:
com.microsoft.sqlserver.jdbc.SQLServerDriver
RazorSQL, on the same machine, connects without error using these settings:
Driver Class: com.microsoft.sqlserver.jdbc.SQLServerDriver
Driver Location: \Program Files (x86)\RazorSQL\drivers\sqlserver\sqljdbc.jar
As a result, we set the CLASSPATH to same location with this command:
set CLASSPATH=C:\Program Files (x86)\RazorSQL\drivers\sqlserver\sqljdbc.jar
...but when running the code below - we still get the same ClassNotFound error.
This is our Python code:
jclassname = "com.microsoft.sqlserver.jdbc.SQLServerDriver"
database = "our_database_name"
db_elem = ";databaseName={}".format(database) if database else ""
host = "###.##.###.###" # ip address
port = "1433"
user = "user_name"
password = "password"
url = (
jdbc:sqlserver://{host}:{port}{db_elem}"
";user={user};password={password}".format(
host=host, port=port, db_elem=db_elem,
er=user, password=password)
)
print url
driver_args = [url]
jars = None
libs = None
db = jaydebeapi.connect(jclassname, driver_args, jars=jars,
libs=libs)
This is how we are running our Python script:
C:\jython2.7.0\bin\jython.exe C:\path_to_our_script.py
How is that RazorSQL is connecting fine - but somehow Python cannot? How do we remove this CLASSPATH error?
You have to load the JARs at runtime using the system Classloader.
Please refer to this answer.
The following code snippet has been taken from this Gist.
def loadJar(jarFile):
'''load a jar at runtime using the system Classloader (needed for JDBC)
adapted from http://forum.java.sun.com/thread.jspa?threadID=300557
Author: Steve (SG) Langer Jan 2007 translated the above Java to Jython
Reference: https://wiki.python.org/jython/JythonMonthly/Articles/January2007/3
Author: seansummers#gmail.com simplified and updated for jython-2.5.3b3+
>>> loadJar('jtds-1.3.1.jar')
>>> from java import lang, sql
>>> lang.Class.forName('net.sourceforge.jtds.jdbc.Driver')
<type 'net.sourceforge.jtds.jdbc.Driver'>
>>> sql.DriverManager.getDriver('jdbc:jtds://server')
jTDS 1.3.1
'''
from java import io, net, lang
u = io.File(jarFile).toURL() if type(jarFile) <> net.URL else jarFile
m = net.URLClassLoader.getDeclaredMethod('addURL', [net.URL])
m.accessible = 1
m.invoke(lang.ClassLoader.getSystemClassLoader(), [u])
if __name__ == '__main__':
import doctest
doctest.testmod()
Also look at - https://wiki.python.org/jython/JythonMonthly/Articles/January2007/3
Followings are my requirement:
Check if the Java is installed
Check if it's installed in a custom directory
if it's, then save the directory path in a variable
Otherwise detect the version and save the standard path in a variable
Below is the code that detects the version and save the standard path to a variable
Problems with my code:
If both 32 and 64 bit is installed it detects the both ..My aim is to detect only 64 bit in case both is installed.
if DirExists(ExpandConstant('{pf32}\java\')) then Is this what i can use to detect custom directory?
I don't think the above code is the right way to find custom directory of java. if the user installed in a different folder other than Java. the other problem is if we uninstall java it doesn't delete the folder java/JRE.
I'm using #TLama's code from Need help on Inno Setup script - issue in check the jre install
[Code]
#define MinJRE "1.7.0"
#define WebJRE "http://www.oracle.com/technetwork/java/javase/downloads/jre6downloads-1902815.html"
function IsJREInstalled: Boolean;
var
JREVersion: string;
JREPath:string
begin
{ read JRE version }
Result := RegQueryStringValue(HKLM32, 'Software\JavaSoft\Java Runtime Environment',
'CurrentVersion', JREVersion);
MsgBox('JAVA 32 bit detected.', mbInformation, MB_OK);
JREPath := 'C:\Program Files (x86)\Java'
{ if the previous reading failed and we're on 64-bit Windows, try to read }
{ the JRE version from WOW node }
if not Result and IsWin64 then
Result := RegQueryStringValue(HKLM64, 'Software\JavaSoft\Java Runtime Environment',
'CurrentVersion', JREVersion);
MsgBox('JAVA 64 bit detected.', mbInformation, MB_OK);
JREPath := 'C:\Program Files\Java'
{ if the JRE version was read, check if it's at least the minimum one }
if Result then
Result := CompareStr(JREVersion, '{#MinJRE}') >= 0;
end;
function InitializeSetup: Boolean;
var
ErrorCode: Integer;
begin
Result := True;
{ check if JRE is installed; if not, then... }
if not IsJREInstalled then
begin
{ show a message box and let user to choose if they want to download JRE; }
{ if so, go to its download site and exit setup; continue otherwise }
if MsgBox('Java is required. Do you want to download it now ?',
mbConfirmation, MB_YESNO) = IDYES then
begin
Result := False;
ShellExec('', '{#WebJRE}', '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;
end;
end;
JRE installation path is stored in registry like this:
[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment]
"CurrentVersion"="1.8"
[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\1.8]
"JavaHome"="C:\\Program Files\\Java\\jre1.8.0_172"
You can retrieve the installation path of the latest version (with 64-bit preference) using a code like this:
const
JavaKey = 'SOFTWARE\JavaSoft\Java Runtime Environment';
function GetJavaVersionAndPath(
RootKey: Integer; var JavaVersion: string; var JavaPath: string): Boolean;
var
JREVersion: string;
begin
Result :=
RegQueryStringValue(RootKey, JavaKey, 'CurrentVersion', JavaVersion) and
RegQueryStringValue(RootKey, JavaKey + '\' + JavaVersion, 'JavaHome', JavaPath);
end;
{ ... }
var
JavaVersion: string;
JavaPath: string;
begin
if GetJavaVersionAndPath(HKLM64, JavaVersion, JavaPath) then
begin
Log(Format('Java %s 64-bit found in "%s"', [JavaVersion, JavaPath]));
end
else
if GetJavaVersionAndPath(HKLM32, JavaVersion, JavaPath) then
begin
Log(Format('Java %s 32-bit found in "%s"', [JavaVersion, JavaPath]));
end
else
begin
Log('No Java found');
end;
end;
Depending on which JRE you have installed, that registry data may not be there. A more generic solution is probably preferable.
I wanted something I could use across multiple Inno Setup projects, so I wrote a DLL for detecting Java details (home directory, etc.):
https://github.com/Bill-Stewart/JavaInfo
Download from here: https://github.com/Bill-Stewart/JavaInfo/releases
The download includes a sample Inno Setup .iss script that demonstrates how to use the DLL functions.
I'm currently trying to build a Bazel 0.11.1 workspace with projects that use different Java language levels. The actual application uses Java 7, but for some code that won't ship, I want to settle with a more recent Java version to be able to use the new language features.
I can solve this to some extent by using --javacopt in .bazelrc, setting -source 1.7 -target 1.7 and override the defaults on a project level with the javacopts attribute, but this is not enough to ensure proper Java 7 compatibility when compiling with a more recent Java version. For this I really need to compile Java 7 projects against a Java 7 classpath as well.
The only way to use a custom bootclasspath seems to be via java_toolchain. It works. But I could not found a way to use different bootclasspaths for different projects, because the toolchain affects all projects and unlike with javacopts cannot be overridden at the project level.
Is this a usecase that is simply not (yet?) possible with Bazel? Or is there some trickery to make it work?
It turns out there is a way: write a custom rule that performs compilation.
The java_common module provides an interface to the compiler.
library.bzl
def _impl(ctx):
deps = []
for dep in ctx.attr.deps:
if java_common.provider in dep:
deps.append(dep[java_common.provider])
output_jar = ctx.new_file("lib{0}.jar".format(ctx.label.name))
runtime = java_common.JavaRuntimeInfo
compilation_provider = java_common.compile(
ctx,
source_jars = ctx.files.srcs_jars,
source_files = ctx.files.srcs,
output = output_jar,
javac_opts = ctx.attr.javac_opts,
deps = deps,
strict_deps = ctx.attr.strict_deps,
java_toolchain = ctx.attr.toolchain,
host_javabase = ctx.attr._host_javabase,
resources = ctx.files.resources,
neverlink = ctx.attr.neverlink,
)
return struct(
files = depset([output_jar]),
providers = [compilation_provider],
)
library = rule(
implementation = _impl,
attrs = {
"srcs_jars": attr.label_list(allow_files=True),
"srcs": attr.label_list(allow_files=True),
"javac_opts": attr.string_list(default=[]),
"deps": attr.label_list(),
"strict_deps": attr.string(default="ERROR"),
"toolchain": attr.label(default=Label("#bazel_tools//tools/jdk:toolchain")),
"sourcepath": attr.label_list(),
"resources": attr.label_list(),
"neverlink": attr.bool(default=False),
"_host_javabase": attr.label(default=Label("#local_jdk//:jdk")),
},
fragments = ["java"],
)
This rule I can now use to set a different toolchain for compilation.
BUILD
load('//build/jdk:library.bzl', 'library')
library(
name = "test",
srcs = glob(["src/main/java/**/*.java"]),
# data = glob(["src/main/resources/**"]),
toolchain = "//build/jdk:jdk8",
deps = ["..."],
)
Unfortunately I'm not 100% there yet. java_common.compile does not seem to have an equivalent for the data attribute of java_library, but for the most part the toolchain problem is solved.
Chef supports execution as non-root user:
https://docs.chef.io/ctl_chef_client.html#run-as-non-root-user
But if the Chef recipe requires action with root access, then it will not work.
Does one of the Chef recipe to install Java support non-root installation? I didn't find reply in their documentation.
https://supermarket.chef.io/cookbooks/java, with java_home attribute value set to user accessible directory then it should be good.
In general most community cookbooks expect to run as root, so you'll likely have to write your own.
I've been able to install java as non-root user by using following code in recipes / default.rb:
arch = node['java']['arch']
jdk_version = node['java']['jdk_version']
tarball_url = node['java']['jdk'][jdk_version][arch]['url']
tarball_checksum = node['java']['jdk'][jdk_version][arch]['checksum']
bin_cmds = []
java_home = node['java']['java_home']
java_ark 'jdk' do
url tarball_url
checksum tarball_checksum
bin_cmds bin_cmds
app_home java_home
owner node['current_user']
action :install
end
And in attributes / default.rb file:
set['java']['jdk_version'] = '7'
set['java']['java_home'] = "/home/jpmat/jdk#{node['java']['jdk_version']}"
set['java']['oracle']['accept_oracle_download_terms'] = 'true'
Anyone have a snippet of how to use the vSphere VI Java API to extract the values in the 'Annotations' section of the 'Summary' tab for a VM? I have looked around a lot as well as combed through the API docs but haven't seen it anywhere.
Have a look at the API Documentation of VirtualMachineConfigSpec first .
Then you can do this from java
VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
configSpec.setAnnotation = "Your annotation string here"
reconfigVM_Task(vmMOR, configSpec);
I did this in Perl SDK, but re-doing it to use Java API should be easy.
You get the annotations from Virtual Machine object which has property named summary of class VirtualMachineSummary which has config of class VirtualMachineConfigSummary which has a annotation field of type string which is what you need.
my $vmname = "vmname you are looking for";
# Get all VMs
my $vms = Vim::find_entity_views(
view_type => 'VirtualMachine',
filter => {"config.name" => qr/^$vmname$/i},
);
# Iterate over the VMs, getting their annotations
foreach my $vm (#{ $vms }) {
my $notes = $vm->summary->config->annotation;
my $name = $vm->summary->config->name;
if (not defined $notes) {
print " - VM: $name has no notes\n";
}
elsif ($notes =~ m/^\$*/) {
print " - VM: $name has empty notes\n";
}
else {
print " - VM: $name notes: '$notes'\n";
}
}
Here is the full code: https://communities.vmware.com/message/2613855#2613855