JNA - Ubuntu - XGetInputFocus - java

OS: Ubuntu 16.04
JNA: 4.2.X
JDK: 1.8.0u111
I'm trying to get the currently focused window programmaticaly on a JavaFX application.
if (Platform.isLinux()) {
final X11 x11 = X11.INSTANCE;
final XLib xlib = XLib.INSTANCE;
X11.Display display = x11.XOpenDisplay(null);
X11.Window window = new X11.Window();
Pointer pointer = Pointer.NULL;
xlib.XGetInputFocus(display, window, pointer); // << ERROR
X11.XTextProperty name = new X11.XTextProperty();
x11.XGetWMName(display, window, name);
System.out.println(name.toString());
}
public interface XLib extends StdCallLibrary {
XLib INSTANCE = (XLib) Native.loadLibrary("/usr/lib/x86_64-linux-gnu/libX11.so", XLib.class);
int XGetInputFocus(X11.Display display, X11.Window focus_return, Pointer revert_to_return);
}
But it doesn't work and throws this exception :
java.lang.IllegalArgumentException: Unrecognized calling convention: 63
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:390)
at com.sun.jna.Function.invoke(Function.java:323)
at com.sun.jna.Library$Handler.invoke(Library.java:236)
at com.sun.proxy.$Proxy1.XGetInputFocus(Unknown Source)
at application.Main.start(Main.java:33)
Is this line correct ?
XLib INSTANCE = (XLib) Native.loadLibrary("/usr/lib/x86_64-linux-gnu/libX11.so", XLib.class);
I tested with an older version of JNA (4.1.X) and the error changed for :
Unrecognized calling convention: 1
Debug log with -Djna.debug_load=true
Looking in classpath from sun.misc.Launcher$AppClassLoader#73d16e93 for /com/sun/jna/linux-x86-64/libjnidispatch.so
Found library resource at jar:file:/home/puglic/eclipse/jna-4.2.2.jar!/com/sun/jna/linux-x86-64/libjnidispatch.so
Looking for library 'X11'
Adding paths from jna.library.path: null
Trying libX11.so
Found library 'X11' at libX11.so
Looking for library 'X11'
Adding paths from jna.library.path: null
Trying libX11.so
Found library 'X11' at libX11.so
java.lang.IllegalArgumentException: Unrecognized calling convention: 63

Your XLib definition uses StdCallLibrary, which only makes sense on 32-bit windows systems. It should simply be Library, or derive from the JNA contrib-defined version.
You're basically asking for a calling convention that does not exist.

Related

Java call C library using native-image from GraalVM

I have a simple project: https://github.com/MarcoLunar/native-pid-test
All what it is doing is calling getpid from C library. Project is as simple as:
public static void main(String[] args) throws Exception {
System.out.println("start");
C_lib cLib = Native.loadLibrary("c", C_lib.class);
int getpid = cLib.getpid();
System.out.println("pid = " + getpid);
System.out.println("end");
}
When launching from IDE everything works fine:
start
pid = 155080
end
When trying to build using native-image from GraalVM I got this error:
[simpletest:155323] compile: 2,597.81 ms, 2.05 GB
Fatal error:org.graalvm.compiler.graph.GraalGraphError: java.lang.NullPointerException
at node: 43|&
at method: Object com.oracle.svm.reflect.JNIGeneratedMethodSupport_getFieldOffsetFromId_5041c78d77a7b3d62103393b72fc35d80d2cc709.invoke(Object, Object[])
at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.tryCanonicalize(CanonicalizerPhase.java:397)
at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.processNode(CanonicalizerPhase.java:325)
at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.processWorkSet(CanonicalizerPhase.java:302)
at org.graalvm.compiler.phases.common.CanonicalizerPhase$Instance.run(CanonicalizerPhase.java:264)
at org.graalvm.compiler.phases.common.CanonicalizerPhase.run(CanonicalizerPhase.java:177)
at org.graalvm.compiler.phases.common.CanonicalizerPhase.run(CanonicalizerPhase.java:73)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:214)
at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:147)
at com.oracle.svm.hosted.code.CompileQueue.doInlineTrivial(CompileQueue.java:587)
at com.oracle.svm.hosted.code.CompileQueue.access$000(CompileQueue.java:156)
at com.oracle.svm.hosted.code.CompileQueue$TrivialInlineTask.run(CompileQueue.java:284)
at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:173)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Caused by: java.lang.NullPointerException
at org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.tryConstantFold(BinaryArithmeticNode.java:120)
I have tried many times, many different solutions ... but for now I have no more to check.
I am asking for help in repairing the project. I think this is possible, because with some configurations I have the same error as in https: //github.com/oracle/graal/issues/2261 ... where someone fixed it ... but didn't write the solution: (
I think currently JNA doesn't work in native image. You can use JNI if that's possible. Or you can use another interface to native code that will work specifically in the native images. Some info can be found in the javadoc of org.graalvm.nativeimage.c and its subpackages: https://www.graalvm.org/sdk/javadoc/index.html?org/graalvm/nativeimage/c/package-summary.html
Here's an example of using it: https://www.praj.in/posts/2020/opengl-demo-using-graalvm/

No such field exception while loading "scl" field from Classloader

I am moving my code from JDK 8 to Open JDK 12. While doing so, I am facing following issue :
java.lang.NoSuchFieldException: scl
while trying to call ClassLoader.class.getDeclaredField("scl"). This was working fine in Java 8 but no longer works in newer Java versions.
I did some findings and believe it has got to do with the way working of reflection and use of internal Java packages have changed since Java 8.
Set<URL> classLoaderUrls = computeClassLoaderUrls();
ClassLoader bootstrapClassLoader = ClassLoader.getSystemClassLoader().getParent();
this.classLoader = new URLClassLoader(classLoaderUrls.toArray(new URL[classLoaderUrls.size()]), bootstrapClassLoader);
Field systemClassLoaderField = ClassLoader.class.getDeclaredField("scl");
systemClassLoaderField.setAccessible(true);
this.initialSystemClassLoader = (ClassLoader) systemClassLoaderField.get(null);
systemClassLoaderField.set(null, this.classLoader);
I want to know , if the way to access these classloader and its fields has changed or should I use some other field instead of scl. Thanks

z3 java api using mkOptimize

I am using the optimization option of z3 in the java api via context.mkOptimize(). When I execute my code it will show me the following error:
java.lang.UnsatisfiedLinkError: com.microsoft.z3.Native.INTERNALmkOptimize(J)J
My Code:
Context context = new Context();
Optimize mkOptimize = context.mkOptimize();
IntExpr intTest = context.mkIntConst("test");
IntExpr intTen = context.mkInt(10);
BoolExpr assertInt = context.mkLe(intTest, intTen);
mkOptimize.Add(assertInt);
mkOptimize.MkMaximize(intTest);
mkOptimize.Check();
Am I doing something wrong or is this a bug in the java api?
(The exception is thrown when creating the optimize object in the second line)
Found the problem. It was due to the system path which was pointing to two different versions of z3 libraries.

Change final variable defined in another java file

I'm programming a mod.
Here's the code:
package net.minecraft.client.gui;
import java.io.IOException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
public class GuiButton extends Gui {
public static final ResourceLocation buttonTextures = new ResourceLocation("textures/gui/widgets.png");
As you can see, there's the variable buttonTextures and its resource location is "textures/gui/widgets.png". And I also have a second one and what I want to do is to change the buttonTextures with this second Java file when I execute it.
I just need to change the resource location of buttonTextures to my own path, but by an other Java file. Maybe it can be done by re-writing the code with the second script, I really have no clue.
What I'm making:
A PAYDAY 2 Mod for Minecraft. And of course, I'm starting with the menu. So I have two main menus. To switch to my menu, there's a button which you have to press. When you do that, it changes its texture. But the problem is, that it can't change the button textures to textures/gui/PAYDAY2widgets.png, because the variable is final.
As you can see, the first file is called GuiButton.
I made a copy of that file, called it GuiPAYDAY2Button.java, and set the path to my path to the texture (textures/gui/PAYDAY2widgets.png).
Now if I add that to the | (I changed the variables from GuiButton to GuiPAYDAY2Button, but then the game crashes after switching to the PAYDAY2 menu) | GuiPAYDAY2MainMenu.java file (the copy of the GuiMainMenu.javafile).
I also changed GuiButton to GuiPAYDAY2Button(in the GuiPAYDAY2MainMenu.java file), so it's directed to that file.
As I was talking about the crashing, this is the crash-report:
---- Minecraft Crash Report ---- // I feel sad now :(
Time: 8.4.15 21:58 Description: Rendering screen
java.lang.ClassCastException: net.minecraft.client.gui.GuiPAYDAY2Button cannot be cast to net.minecraft.client.gui.GuiButton
at net.minecraft.client.gui.GuiScreen.drawScreen(GuiScreen.java:99)
at net.minecraft.client.gui.GuiPAYDAY2MainMenu.drawScreen(GuiPAYDAY2MainMenu.java:453)
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1167)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1127)
at net.minecraft.client.Minecraft.run(Minecraft.java:410)
at net.minecraft.client.main.Main.main(Main.java:114)
at Start.main(Start.java:11)
A detailed walkthrough of the error, its code path and all known details is as follows:
-- Head --
Stacktrace:
at net.minecraft.client.gui.GuiScreen.drawScreen(GuiScreen.java:99)
at net.minecraft.client.gui.GuiPAYDAY2MainMenu.drawScreen(GuiPAYDAY2MainMenu.java:453)
-- Screen render details --
Details:
Screen name: net.minecraft.client.gui.GuiPAYDAY2MainMenu
Mouse location: Scaled: (202, 11). Absolute: (405, 456)
Screen size: Scaled: (427, 240). Absolute: (854, 480). Scale factor of 2
Stacktrace:
at net.minecraft.client.renderer.EntityRenderer.updateCameraAndRender(EntityRenderer.java:1167)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1127)
at net.minecraft.client.Minecraft.run(Minecraft.java:410)
at net.minecraft.client.main.Main.main(Main.java:114)
at Start.main(Start.java:11)
-- System Details --
Details:
Minecraft Version: 1.8
Operating System: Windows 7 (amd64) version 6.1
Java Version: 1.8.0_31, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 707532608 bytes (674 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
Launched Version: mcp
LWJGL: 2.9.1
OpenGL: GeForce GTX 460 v2/PCIe/SSE2 GL version 4.5.0 NVIDIA 347.25, NVIDIA Corporation
GL Caps: Using GL 1.3 multitexturing. Using GL 1.3 texture combiners. Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported. Shaders are available because OpenGL 2.1 is supported. VBOs are available because OpenGL 1.5 is supported.
Using VBOs: No
Is Modded: Very likely; Jar signature invalidated
Type: Client (map_client.txt)
Resource Packs: []
Current Language: English (US)
Profiler Position: N/A (disabled)
UPDATE
I made a video some hours ago and it's a showcase to this mod. Maybe you'll understand what I want..: https://www.youtube.com/watch?v=ocHT7LdNBYY
Ok, I made the extending script look like this:
package net.minecraft.client.gui;
import net.minecraft.util.ResourceLocation;
public class GuiButtonTexureChange extends GuiButton {
public static ResourceLocation buttonTextures = new ResourceLocation("textures/gui/PAYDAY2widgets.png");
// Now this part is needed to be here (otherwise it throws errors):
public GuiButtonTexureChange(int buttonId, int x, int y, int widthIn, int heightIn, String buttonText) {
super(buttonId, x, y, widthIn, heightIn, buttonText); // TODO Auto-generated constructor stub
}
}
If you cannot modify some Java code (for instance it is part of a library), you can still overwrite any Java class you like.
Create another source folder (speaking in terms of Eclipse here), and inside that the exact package and file as the class you want to edit. In your case it should be package net.minecraft.client.gui and file GuiButton.java.
Now, if your own file comes first in classpath, you have successfully overwritten a class. All the other code of the library still works as it used to.
To ensure that your own code comes first in classpath when working with Eclipse:
Project properties -> Java Build Path -> Order and Export
It is probably wise to copy the existing code (of GuiButton) into your own file to have the same starting point, and then do your modifications on the code.
Depending on your security manager settings, you could change the path string at runtime via reflection.
Example :
static void setFinalStatic(final Field field, final Object instance, final Object newValue) throws Exception {
field.setAccessible(true);
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL & ~Modifier.PRIVATE);
field.set(instance, newValue);
}
public final static void main(String[] args) throws Exception {
String path = "initialPath";
final char[] after = "sneakyPath".toCharArray();
setFinalStatic(path.getClass().getDeclaredField("value"), path, after);
setFinalStatic(path.getClass().getDeclaredField("offset"), path, 0);
setFinalStatic(path.getClass().getDeclaredField("count"), path, after.length);
System.out.println(path);
}

Integrating java and .net dll using JNI

I am doing a small project it is a interoperability of java and .net dll.
Focus:
I just have a java file which calls the .net dll which is created by using C# and CPP and MCPP..
The program is just a hello world Program..
I just refer the below mentioned sites.
http://www.codeproject.com/Articles/378826/How-to-wrap-a-Csharp-library-for-use-in-Java
http://www.codeproject.com/Articles/13093/C-method-calls-within-a-Java-program
Finally I just get some ideas and finally did this with some errors.
Coding:
#using "mscorlib.dll"
#using "CSharpHelloWorld.netmodule"
using namespace System;
public __gc class HelloWorldC
{
public:
// Provide .NET interop and garbage collecting to the pointer.
CSharpHelloWorld __gc *t;
HelloWorldC() {
t = new CSharpHelloWorld();
// Assign the reference a new instance of the object
}
// This inline function is called from the C++ Code
void callCSharpHelloWorld() {
t->displayHelloWorld();
}
};
Errors:
Error 1 error C4980: '__gc' : use of this keyword requires /clr:oldSyntax command line option
Error 2 error C3699: 'interior_ptr' : cannot use this indirection on type 'CSharpHelloWorld'
Error 3 error C2750: 'CSharpHelloWorld' : cannot use 'new' on the reference type; use 'gcnew' instead
Error 4 error C2440: '=' : cannot convert from 'CSharpHelloWorld *' to 'CSharpHelloWorld ^' 11 WindowsComponentProject
Error 5 error C2011: 'HelloWorldC' : 'class' type redefinition 6 WindowsComponentProject
Error 6 error C3699: '*' : cannot use this indirection on type 'HelloWorldC' 18 WindowsComponentProject
Error 7 error C2750: 'HelloWorldC' : cannot use 'new' on the reference type; use 'gcnew' instead 18 WindowsComponentProject
Error 8 error C2440: 'initializing' : cannot convert from 'HelloWorldC *' to 'HelloWorldC ^' 18 WindowsComponentProject
Error 9 error C2027: use of undefined type 'HelloWorldC' 21 WindowsComponentProject
Error 10 error C2227: left of '->callCSharpHelloWorld' must point to class/struct/union/generic type 21 WindowsComponentProject
I just seek some sites for the solution to change the properties of CLR but it doesn't works kindly help me over it.. thanks in advance !!!
You are using old Managed C++ syntax.
New one is called C++/CLI.
You create a reference type by prefixing the class declaration with ref keyword. Use ^ to declare a reference variable as in CSharpHelloWorld^ t.
gcnew is what you use to create an object in managed heap.
You should modify your class as shown below.
using namespace System;
public ref class HelloWorldC {
public:
// Provide .NET interop and garbage collecting to the pointer.
CSharpHelloWorld^ t;
HelloWorldC() {
t = gcnew CSharpHelloWorld();
// Assign the reference a new instance of the object
}
// This inline function is called from the C++ Code
void callCSharpHelloWorld() {
t->displayHelloWorld();
}
};

Categories

Resources