Can't obtain class com.sun.jna.CallbackReference

182 views
Skip to first unread message

Roy Zhang

unread,
Jul 13, 2023, 9:16:37 PM7/13/23
to Java Native Access
Hi,

I just added JNA in my project. The dependencies are also added to pom.xml file. My project could build and test successfully. But when the upper application uses my shaded JAR, it complains the class 'com.sun.jna.CallbackReference' could not be found. I have tried different ways by asking chatGPT and Bing, but still could not fix the problem. Does anyone have any idea about this? Thanks in advance!

--code
import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Psapi;
import com.sun.jna.platform.win32.WinNT;


--dependencies
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.13.0</version>
</dependency>

-error info
Reason: can't load class 'my.main.class'
    Can't obtain class com.sun.jna.CallbackReference

Best,
Roy

Roy Zhang

unread,
Jul 13, 2023, 9:39:38 PM7/13/23
to Java Native Access
I am using Java 8. I also checked class path, it is ".". Used jar tf to check the shaded jar, I could see CallbackReference is included.


com/sun/
com/sun/jna/
com/sun/jna/AltCallingConvention.class
com/sun/jna/Callback$UncaughtExceptionHandler.class
com/sun/jna/Callback.class
com/sun/jna/CallbackParameterContext.class
com/sun/jna/CallbackProxy.class
com/sun/jna/CallbackReference$AttachOptions.class
com/sun/jna/CallbackReference$DefaultCallbackProxy.class
com/sun/jna/CallbackReference$NativeFunctionHandler.class
com/sun/jna/CallbackReference.class

Tres Finocchiaro

unread,
Jul 14, 2023, 10:34:14 AM7/14/23
to jna-...@googlegroups.com
Does the same problem occur when you pass "-Djna.nosys=true" as a JVM parameter?

Per:

Furthermore, does the shaded plugin modify the location of any native components?  If so, you may need to extract any native libraries manually.

Per:

Tres Finocchiaro

unread,
Jul 14, 2023, 10:38:32 AM7/14/23
to jna-...@googlegroups.com
Furthemore, if you're able to create a small project to reproduce, please share.s

Roy Zhang

unread,
Jul 14, 2023, 4:22:48 PM7/14/23
to Java Native Access
It is called in an application, I could not specify  "-Djna.nosys=true" . I did not modify the location of any native components.

I have tried to make a simple test project. It works fine. But once move the code to my project, it has this problem. The call stack is like this.

java.lang.UnsatisfiedLinkError: Can't obtain class com.sun.jna.CallbackReference
at com.sun.jna.Native.initIDs(Native Method)
at com.sun.jna.Native.<clinit>(Native.java:248)
at com.sun.jna.platform.win32.Kernel32.<clinit>(Kernel32.java:44)


Here is my test project

--code
package com.example;


import com.sun.jna.Native;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.Psapi;
import com.sun.jna.platform.win32.WinNT;

public class ApplicationNameExample {
public static void main(String[] args) {

// Get the process ID of the current Java process
int processId = Kernel32.INSTANCE.GetCurrentProcessId();

// Get the handle of the current Java process
WinNT.HANDLE processHandle = Kernel32.INSTANCE.OpenProcess(
Kernel32.PROCESS_QUERY_INFORMATION | Kernel32.PROCESS_VM_READ,
false,
processId
);

Psapi psapi = Psapi.INSTANCE;
char[] buffer = new char[1000];
psapi.GetModuleFileNameExW(processHandle, null, buffer, 1000);
String processName = Native.toString(buffer);
System.out.println("Application Name: " + processName);

//System.out.println("This is a test");
}
}


--pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>my-test-project</artifactId>
<version>1.0.0</version>

<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>

<dependencies>
<!-- Other dependencies -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.10.0</version>

</dependency>

<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.10.0</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin><!-- Output an additional jar with the dependencies shaded. -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.ApplicationNameExample</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

Matthias Bläsing

unread,
Jul 14, 2023, 5:09:00 PM7/14/23
to jna-...@googlegroups.com
Hi,

Am Freitag, dem 14.07.2023 um 13:22 -0700 schrieb 'Roy Zhang' via Java Native Access:
> It is called in an application, I could not specify  "-
> Djna.nosys=true" . I did not modify the location of any native
> components.
>
> I have tried to make a simple test project. It works fine. But once
> move the code to my project, it has this problem. The call stack is
> like this.
>
> java.lang.UnsatisfiedLinkError: Can't obtain class
> com.sun.jna.CallbackReference
> at com.sun.jna.Native.initIDs(Native Method)
> at com.sun.jna.Native.<clinit>(Native.java:248)
> at
> com.sun.jna.platform.win32.Kernel32.<clinit>(Kernel32.java:44)

I had a look at the native code and in general classloading must still
work, as CallbackReference is one of the last classes to be loaded.

The I thought about what might cause so differential problems and I
have a hunch:

Check the dependencies (including all transitive depdencies) of your
main project. Check each jar if you find a second set of JNA classes.
If the classes are not consistent, they will fail to properly load.

An additional debugging option is to remove your native call and at
that point call `Class.forName("com.sun.jna.CallbackReference")`. This
will try to load the `CallbackReference` class and should also fail.
The difference is, that now you should get a stack trace and better
error report why class loading fails.

HTH

Matthias

Roy Zhang

unread,
Jul 17, 2023, 2:25:36 PM7/17/23
to Java Native Access
Hi,

Thanks for your info. I have checked the dependency. There is no other set of jna package.

Here is my example code to load myClass. The error stack is also listed. 

--example code
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

public class Main {
@SuppressWarnings("unchecked")
private Class Load(String fileName, String className) {
try {
File file = new File(fileName);
URLClassLoader loader = new URLClassLoader(
new URL[] { file.toURI().toURL() },
this.getClass().getClassLoader()
);
Class classToLoad = Class.forName(className, true, loader);
return classToLoad;
} catch (Exception e) {
System.err.printf("Load failed: %s\n%n", e.getMessage());
e.printStackTrace();
}
return null;

}

public static void main(String[] args) {
Main instance = new Main();
instance.Load(
path_to_my_shaded_jar,
myClass);
}
}

--error stack
java.lang.UnsatisfiedLinkError: Can't obtain class com.sun.jna.CallbackReference
        at com.sun.jna.Native.initIDs(Native Method)
        at com.sun.jna.Native.<clinit>(Native.java:248)
        at com.sun.jna.platform.win32.Kernel32.<clinit>(Kernel32.java:44)
        at  myClass.getApplicationName(xxxx.java:190)
        at myClass.<clinit>(xxxx.java:60)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
at Main.Load(Main.java:14)
at Main.main(Main.java:25)

Thanks,
Roy

Matthias Bläsing

unread,
Jul 17, 2023, 5:51:49 PM7/17/23
to Java Native Access
Hi,

sorry, no idea anymore. My advise now: boil down your project to the minimum, so that you can share it. Then we can have a look.

Greetings

Matthias
Reply all
Reply to author
Forward
0 new messages