I have a java application that uses jna to call a 64 bit third party DLL to communicate with scanners (with native 64 bit drivers). I am receiving an invalid memory access error with the combination of windows 10 / java11 / jna that I do not receive with any other combination.
This code works fine on all the following without errors:
Windows 7 / 64 bit java 8 runtime
Windows 7 / 64 bit java 11 runtime
Windows 10 / 64 bit java 8 runtime
I am using latest and greatest jna (5.3.1) and have tried older versions as well, with the same result.
/* Open Scanner */
EZT.TWAIN_SetHideUI(true);
if (EZT.TWAIN_GetSourceList()) {
if (!EZT.TWAIN_OpenDefaultSource()) {
throw new RuntimeException("Cannot open scanner");
}
}
/* Retrieve scanner capabilities for resolution */
int hcon = EZT.TWAIN_Get(EZLibrary.ICAP_XRESOLUTION);
if (hcon != 0) {
int resolutions[] = new int[EZT.CONTAINER_ItemCount(hcon)];
...
}
.....
private interface EZLibrary extends Library {
int ICAP_XRESOLUTION = 4376;
void TWAIN_SetHideUI(boolean bHide);
boolean TWAIN_GetSourceList();
boolean TWAIN_OpenDefaultSource();
int TWAIN_Get(int uCap);
int CONTAINER_ItemCount(int hcon);
}
The call to "EZT.CONTAINER_ItemCount(hcon)" in this example returns an Invalid Memory Access Error. However, when this code is a part of my larger application and not this sample application, the same code sequence throws the Invalid Memory access error up higher on "EZT.TWAIN_OpenDefaultSource()".
So, in summary:
windows 7 / java 8 : as expected results
windows 7 / java 11: as expected results
windows 10 / java 8: as expected results
windows 10 / java 11:
java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:426)
at com.sun.jna.Function.invoke(Function.java:361)
at com.sun.jna.Library$Handler.invoke(Library.java:265)
at com.sun.jna.Native$3.invoke(Native.java:1202)
at $Proxy0.CONTAINER_ItemCount(Unknown Source)
My question becomes is there an issue with JNA with win 10 / java 11 or is it something in the third party code, or something I'm doing wrong?
I did end up finding a solution for this.
I am not entirely sure why, but for 64 bit my JNA implementation needed:
Long TWAIN_Get(int uCap);
Long TWAIN_Acquire(int hwndApp);
With 32 bit it needed to be:
Integer TWAIN_Get(int uCap);
Integer TWAIN_Acquire(int hwndApp);
So to handle both I just use:
Number hcon = EZT.TWAIN_Get(EZTwainPro.ICAP_XRESOLUTION);
Doing this resolved the invalid memory access. I know it is because of the int returned was an unsigned int, but I am not entirely sure why the "long" implementation only works on 64 bit and not 32 bit runtimes. It has to be different in order to have both work. Also, the "long" implementation was only needed for win10, not win7, but it works for win7 too.
I have searched SO and everywhere else and nothing works to fix the unsupported major.minor version 51 error. I uninstalled Java 8 and installed Java 7. No luck.
Thank you for your help.
I am using:
R 3.3.1
Java 8.91
OSX, el capitan
library(NLP)
library(tm)
library(RWeka)
library(rJava)
library((RWekajars))
library(parallel)
options(mc.cores=1)
Here is the R code causing the error:
trigram <- function(x){NGramTokenizer(x,control=Weka_control(min=3,max=3))}
tdm <- TermDocumentMatrix(corpus2,control=list(tokenize=trigram))
Here is the error I get.
Error in .jnew(name) :
java.lang.UnsupportedClassVersionError: weka/core/tokenizers/NGramTokenizer : Unsupported major.minor version 51.0
9 stop(structure(list(message = "java.lang.UnsupportedClassVersionError: weka/core/tokenizers/NGramTokenizer : Unsupported major.minor version 51.0",
call = .jnew(name), jobj = <S4 object of class structure("jobjRef", package = "rJava")>), .Names = c("message",
"call", "jobj"), class = c("UnsupportedClassVersionError", "ClassFormatError",
"LinkageError", "Error", "Throwable", "Object", "Exception", ...
8 .jnew(name)
7 NGramTokenizer(x, control = Weka_control(min = 3, max = 3))
6 .tokenize(doc)
5 FUN(X[[i]], ...)
4 lapply(X = X, FUN = FUN, ...)
3 mclapply(unname(content(x)), termFreq, control)
2 TermDocumentMatrix.VCorpus(corpus2, control = list(tokenize = trigram))
1 TermDocumentMatrix(corpus2, control = list(tokenize = trigram))
I was also using NGramTokenizer(x, control = Weka_control(min = 3, max = 3))
and it was creating errors for me. I came across this tokenizer and it fixed the issue for me.
TrigramTokenizer <-
function(x)
unlist(lapply(ngrams(words(x), 3), paste, collapse = " "), use.names = FALSE)
please see: https://rpubs.com/hokumski/capstone-milestone-week2 for more information
I've been trying to solve this same issue all week. I've been using Java 1.8 which I read is fine. However the problem seems to be in the rJava package that's installing inside of R. Once I installed from rforge.net using the following line everything worked.
install.packages("rJava","http://rforge.net/",type="source")
While I've tried to use the following code snippet with the Groovy in-operator explanation the VerifyError has occured. Have you guys any idea about?
The code and console output is below.
class Hello extends ArrayList {
boolean isCase(Object val) {
return val == 66
}
static void main(args) {
def myList = new Hello()
myList << 55
assert 66 in myList
assert !myList.contains(66)
}
}
The error log:
Exception in thread "main" java.lang.VerifyError: (class: Hello, method: super$1$stream signature: ()Ljava/util/stream/Stream;) Illegal use of nonvirtual function call
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:259)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:116)
The code origin from the topic How does the Groovy in operator work?.
Update:
Groovy Version: 1.8.6 JVM: 1.6.0_45 Vendor: Sun Microsystems Inc. OS: Linux
Check this out.
It's for Java, but generally problem is, that you are using wrong library versions. The class is there, but different version than expected.
http://craftingjava.blogspot.co.uk/2012/08/3-reasons-for-javalangverfiyerror.html
Probably you have messed up Groovy or Java SDK installations.
I would assume that the following code is safe, nevertheless I am getting an NPE while invoking hasMoreElements(). Any ideas what might be wrong?
I should add that I am using Java 1.7.0_55-b13 on Windows, 64 bit.
final List<URL> urls = new ArrayList<URL>();
final String plUri = "META-INF/plugin.xml";
Enumeration<URL> urlsEn =
Thread.currentThread().getContextClassLoader().getResources(pluginsUri);
if (urlsEn != null) {
while (urlsEn.hasMoreElements()) { // NPE happens here
final URL u = urlsEn.nextElement();
urls.add(u);
}
}
Stack trace:
java.lang.NullPointerException
at sun.misc.MetaIndex.mayContain(MetaIndex.java:243)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:830)
at sun.misc.URLClassPath$2.next(URLClassPath.java:273)
at sun.misc.URLClassPath$2.hasMoreElements(URLClassPath.java:283)
at java.lang.ClassLoader$2.hasMoreElements(ClassLoader.java:1322)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilder.getComponentUrls(GuiceComponentFactoryBuilder.java:256)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilder.build(GuiceComponentFactoryBuilder.java:160)
at com.github.jochen.afw.core.guice.GuiceComponentFactoryBuilderTest.testSuccessfullConfiguration(GuiceComponentFactoryBuilderTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
....
I hate to suggest your problem is something so simple, but could pluginsUri be null here? At least in your code snippet, you create a plUri variable but then pass in an unmentioned pluginsUri to ClassLoader.getResources().
From your stack trace, searching for "URLClassPath null pointer exception" uncovered this question which looks to be the same stack trace. In their case the argument to getResources() is clearly null.
Looking at the Java 7 codebase, we see that MetaIndex:243 is:
if (entry.startsWith(conts[i])) {
And entry could be null at this line. Looking higher up the stack, entry looks to be the name argument you passed to ClassLoader.getResources().
This SSCCE:
public class ClassLoaderNPE {
public static void main(String[] args) throws IOException {
Enumeration<URL> urls = ClassLoader.getSystemClassLoader().getResources(null);
System.out.println(urls.hasMoreElements());
}
}
replicates your stack trace (in Java 8, no less):
$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
$ java -cp . ClassLoaderNPE
Exception in thread "main" java.lang.NullPointerException
at sun.misc.MetaIndex.mayContain(MetaIndex.java:242)
at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:995)
at sun.misc.URLClassPath$2.next(URLClassPath.java:288)
at sun.misc.URLClassPath$2.hasMoreElements(URLClassPath.java:298)
at java.lang.ClassLoader$2.hasMoreElements(ClassLoader.java:1278)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at sun.misc.CompoundEnumeration.next(CompoundEnumeration.java:45)
at sun.misc.CompoundEnumeration.hasMoreElements(CompoundEnumeration.java:54)
at ClassLoaderNPE.main(ClassLoaderNPE.java:9)
The JDK does not appear specify what happens if name is null. I've filed a bug to suggest fixing this behavior, or at least clarifying the documentation. I'll update this post if/when Oracle accepts the issue.
Update: The report is tracked as JDK-8136831, and has been fixed in Java 9.
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");