JVMTI native agent (DLL) can not be loaded to a runing Java program - AgentLoadException - native

I struggled on this issue for a few days but didn't get a right answer yet.
Here is the Problem Description:
I wrote a normal Java program (Program-A), and wrote a Windows-based native agent (*.dll, written in C/C++) with Agent_OnLoad, Agent_OnAttach, Agent_OnUnload method, which works fine if using Java command-line flag (-agentlib). Then I wrote another Java program to attach the native agent onto a runing the Java Program-A (see the below code piece for VM attach and loadAgentPath), however I got the exception:
com.sun.tools.attach.AgentLoadException: Failed to load agent library
I tried to change the agentPath (absolute or relative file path) this or that way, none of these works. Should I try some other way to make this work. What I need is to attach a native agent onto a runing java program rather than using command-line flag.
Does anyone know the root cause or a clue for the solution?
BTW, the command line to run attach VM Java code as:
java -Djava.library.path=D:\DevTools\Java7\jre7\bin -classpath .;./tools.jar com.xxx.TestAgentVMAttacher
...
VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(pid); // Note: this code line is executed normally, I am sure the pid is correct
...
agentPath = theFilePath + "/myagent.dll"; // Note: I am sure the dll file path is correct
virtualMachine.loadAgentPath(agentPath,null); // Note: this code line would cause the exception (AgentLoadException) as I mentioned above, no matter how I set the agentPath, even I set it as null, same exception happened.
Environment related info:
- OS: Windows XP
- Java Version: Java(TM) SE Runtime Environment (build 1.7.0-b147)

Eventually I found the answer for my question, I had a wrong method name ('Agent_Attach') in Agent.cpp file, the correct one should be 'Agent_OnAttach', with this fix, my agent lib (.dll) can be loaded to a running Java program now.

Related

jackrabbit - There is an error in invoking javac. A full JDK (not just JRE) is required

I'm learning Jackrabbit and following the documentation to run a standalone server. When I run the command java -jar jackrabbit-standalone-2.16.2.jar and access localhost:8080 on my browser, I get a 500 error saying:
org.apache.jasper.JasperException: PWC6345: There is an error in invoking javac. A full JDK (not just JRE) is required
What am I doing wrong?
Note: I have set my jdk/bin path in my environment variables.Also, my javac command is working properly. I've jdk version 1.8.0_74 and Jackrabbit version 2.16.2
Edit: According to this answer, I tried setting my jdk to my installed jres in eclipse but that didn't solve my problem.
Running the latest jackarabit standalone jar(2.17.3) in my machine(windows 10 and java home pointing in java8 jdk) produced the same errors.
I then executed the rar with java -Djava.home="%JAVA_HOME%" -jar jackrabbit-standalone-2.17.3.jar. Although I got the same error in browser I was able to see errors in the console where I invoked the running command.
One of these error was
can't open C:\Progra~1\Java\jdk1.8.0_144\lib\tzmappings.
Searching my java installation I found that the missing files, are located under jre's installation folder.
So I eventually made the standalone jar to work with:
java -Djava.home="%JAVA_HOME%\jre" -jar jackrabbit-standalone-2.17.3.jar
The initial error is a bit misleading as it refers to javac and not to the missing files.
The whole thing seems to be a bug for me. Please give a try to my workaround and if it works for you consider filing a bug in Jackrabbit's issue tracker platform.
jackrabbit-standalone uses JSP. JSP needs compilation. Compilation needs JDK.
Before running java -jar jackrabbit-standalone-2.16.2.jar do you check your JAVA_HOME, and make sure it refers to a fully-fledged JDK? In short, the bin directory should have javac.
I found that there was another variable in the Path environment System variable preceding my %JAVA_HOME%\bin variable.
You don't have to delete the other variable, but move it down (or move %JAVA_HOME\bin up) to correct the load order.

Decompiling MCP error (version 9.18) returns 'Decompile Failed'

I have decided to take on MCP and have downloaded it, however, when running the decompile.bat, it returns an error.
(I'm running 32-bit Windows 10)
Here is what it returned:
'"C:\Program Files\Java\jdk1.8.0_65\bin\java" -jar runtime\bin\fernflower.jar -din=1 -rbr=1 -dgs=1 -asc=1 -rsy=1 -iec=1 -jvn=1 -log=WARN "-e=jars\libraries\net/java/jinput\jinput\2.0.5\jinput-2.0.5.jar" "-e=jars\libraries\org/lwjgl/lwjgl\lwjgl-platform\2.9.4-nightly-20150209\lwjgl-platform-2.9.4-nightly-20150209-natives-windows.jar" "-e=jars\libraries\com/ibm/icu\icu4j-core-mojang\51.2\icu4j-core-mojang-51.2.jar" "-e=jars\libraries\tv/twitch\twitch-external-platform\4.5\twitch-external-platform-4.5-natives-windows-32.jar" "-e=jars\libraries\org/apache/httpcomponents\httpcore\4.3.2\httpcore-4.3.2.jar" "-e=jars\libraries\org/apache/logging/log4j\log4j-api\2.0-beta9\log4j-api-2.0-beta9.jar" "-e=jars\libraries\org/apache/commons\commons-lang3\3.3.2\commons-lang3-3.3.2.jar" "-e=jars\libraries\net/java/jutils\jutils\1.0.0\jutils-1.0.0.jar" "-e=jars\libraries\net/java/dev/jna\jna\3.4.0\jna-3.4.0.jar" "-e=jars\libraries\com/paulscode\libraryjavasound\20101123\libraryjavasound-20101123.jar" "-e=jars\libraries\net/sf/jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar" "-e=jars\libraries\com/google/guava\guava\17.0\guava-17.0.jar" "-e=jars\libraries\oshi-project\oshi-core\1.1\oshi-core-1.1.jar" "-e=jars\libraries\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar" "-e=jars\libraries\org/apache/commons\commons-compress\1.8.1\commons-compress-1.8.1.jar" "-e=jars\libraries\net/java/dev/jna\platform\3.4.0\platform-3.4.0.jar" "-e=jars\libraries\com/paulscode\codecjorbis\20101023\codecjorbis-20101023.jar" "-e=jars\libraries\com/paulscode\soundsystem\20120107\soundsystem-20120107.jar" "-e=jars\libraries\com/paulscode\librarylwjglopenal\20100824\librarylwjglopenal-20100824.jar" "-e=jars\libraries\org/lwjgl/lwjgl\lwjgl_util\2.9.4-nightly-20150209\lwjgl_util-2.9.4-nightly-20150209.jar" "-e=jars\libraries\commons-codec\commons-codec\1.9\commons-codec-1.9.jar" "-e=jars\libraries\org/apache/httpcomponents\httpclient\4.3.3\httpclient-4.3.3.jar" "-e=jars\libraries\org/lwjgl/lwjgl\lwjgl\2.9.4-nightly-20150209\lwjgl-2.9.4-nightly-20150209.jar" "-e=jars\libraries\commons-io\commons-io\2.4\commons-io-2.4.jar" "-e=jars\libraries\com/mojang\realms\1.7.39\realms-1.7.39.jar" "-e=jars\libraries\com/mojang\authlib\1.5.21\authlib-1.5.21.jar" "-e=jars\libraries\com/google/code/gson\gson\2.2.4\gson-2.2.4.jar" "-e=jars\libraries\tv/twitch\twitch\6.5\twitch-6.5.jar" "-e=jars\libraries\com/paulscode\codecwav\20101023\codecwav-20101023.jar" "-e=jars\libraries\tv/twitch\twitch-platform\6.5\twitch-platform-6.5-natives-windows-32.jar" "-e=jars\libraries\net/java/jinput\jinput-platform\2.0.5\jinput-platform-2.0.5-natives-windows.jar" "-e=jars\libraries\org/apache/logging/log4j\log4j-core\2.0-beta9\log4j-core-2.0-beta9.jar" "-e=jars\libraries\io/netty\netty-all\4.0.23.Final\netty-all-4.0.23.Final.jar" temp/minecraft_ff_in.jar temp\src\minecraft' failed : 1
Decompile failed
This is caused by the decompilation system running out of RAM. I'm not entirely sure why it's happening, but it also was happening to me.
If you're using Minecraft Forge's ForgeGradle, see this. You can either edit the gradle options file ( .gradle/gradle.properties in your user folder) and add org.gradle.jvmargs=-Xmx2G to it, or you can set the options variable to -Xmx2G (in a command prompt, run set GRADLE_OPTS=-Xmx2G and then gradlew setupDecompWorkspace).
However, given that you referenced decompile.bat, you probably are using MCP without Forge. (Which is fine but forge does make mods easier/more compatible; you may want to consider doing this if you're making a more permanent mod rather than just messing about.) In this case, you can edit MCP's configuration to increase the given RAM.
In the MCP folder, open the conf folder and then open mcp.cfg with a text editor of your choice. Then, find this line (near the bottom)
CmdFernflower = %s -jar %s -din=1 -rbr=0 -dgs=1 -asc=1 -log=WARN {indir} {outdir}
and replace it with this:
CmdFernflower = %s -Xmx2G -jar %s -din=1 -rbr=0 -dgs=1 -asc=1 -log=WARN {indir} {outdir}
(You may need to change other lines also adding -Xmx2G before -jar but it doesn't seem to be needed from my experience).
This will run the decompiler with additional RAM.
Alternatively, if you don't want to mess around with the MCP configuration, MCP910 doesn't seem to have this issue. It works with 1.8.0 instead of 1.8.8, but should still do everything you want.
I know, this answer comes very late, but you should install the 64-bit Version of Java. With the 32-Bit Version, it doesn't work...
I don't know if you can install this on your 32-Bit System, but you can try it. On my 86-Bit System (Windows 8) it works!

XOpenDisplay(NULL) fails to connect to X

I was given a fairly large program to compile and run with extremely vague instructions on how to properly configure my system and install the program. I was told to use a Windows, install Cygwin, navigate to the program's base directory, and type "make". I installed Cygwin on a 64-bit Windows 7 in C:\cygwin64 as the main user (I also installed all of the default packages, plus a few extras) and then ran the makefile included with the program (this worked with no problems). When trying to run the executable with a required file argument, I was simply given the error message "cannot connect to X server." Upon examination of the code, it appears that this error was caused by a line setting display=XOpenDisplay(NULL) and then exiting when this resulted in display == NULL. Earlier, "display" had been declared as a variable of type Display. Is there any way I can get the program to connect to the X server? I have been assured that the installation of the program is extremely easy, but I'm not so sure... Thanks in advance.

Purpose of com.ibm.oti.vm.bootstrap.library.path on AIX j9vm JVM

Background
I have a C++ program that loads a JVM internally and then uses JNI to call code in the JVM. This runs on multiple platforms including AIX. However, when starting the JVM on AIX everything is fine until I call some code that needs to access native code supplied as part of the JRE. I then run into this error message:
java.lang.UnsatisfiedLinkError: net (Not found in com.ibm.oti.vm.bootstrap.library.path)
The problem is that the JVM cannot find the shared library libnet.so. If I dump the value of the com.ibm.oti.vm.bootstrap.library.path system property from Java code running in the JVM I see that by default (i.e. not me setting it) it has the value:
<jre-base-dir>/lib/ppc/default:<jre-base-dir>/lib/ppc
From the error message I guessed it would be a good idea to change this to include the dir where libnet.so is located. However, this shared library is in <jre-base-dir>/lib/ppc which is already in the path set by com.ibm.oti.vm.bootstrap.library.path, so it seems the error message is incorrect.
Experimenting with different values for this system property makes me believe that it is used by the AIX j9vm to load the internal JVM shared libraries only (like libjclse7b_26.so) but not the native code implementations (like libnet.so).
My fix
To fix my problem I had to change the LIBPATH environment variable (which is AIX the equivalent of LD_LIBRARY_PATH in e.g. Linux).
$ LIBPATH=<jre-base-dir>/lib/ppc:<jre-base-dir>/lib/ppc/j9vm ./myprogram
Questions
Can anyone shed some light on the real purpose of the system property com.ibm.oti.vm.bootstrap.library.path on AIX when using the j9vm JVM?
Is my fix the correct way to solve the problem or should I use some other system property? (I have tried java.library.path but it does not seem to help.)
In my case it show error message:
java.lang.UnsatisfiedLinkError: awt (Not found in com.ibm.oti.vm.bootstrap.library.path)
I fix my problem by
copy /usr/java6_64/jre/lib/ppc64/libawt.so to /usr/java6_64/jre/lib/ppc64/j9vm and create symbolic link libawt.a to libawt.so
I set LD_LIBRARY_PATH
LD_LIBRARY_PATH="/usr/java6_64/jre/lib/ppc64:/usr/java6_64/jre/lib/ppc64/j9vm"; export LD_
LIBRARY_PATH

Find the commands that jvm was started with during run time (1.6.0_12)

Full story:
I am trying to start up an instance of hudson with a larger memory allocation and I'm currently using scripts owned by root that I can't modify directly to pass arguments. However the script currently passes the $JAVA_ARGS variable when starting up the service. I have exported the required parameters to JAVA_ARGS but the application still appears to be bound by the old memory restrictions.
Question:
Is there a way to find out which command line parameters were used to start up the instance. More specifically I'm looking to find the values that were passed (if any) to Xmx and Xms.
java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) 64-Bit Server VM (build 11.2-b01, mixed mode)
After some searching I came about a pretty simple solution (which I'm a little embarrassed to have missed for so long). You can see the command line to any command running in linux with ps, as long as you pass the correct flags. I just made a call to ps -fHu hudson and was able to see the full command line call to java which showed the passed in parameters.
Since you can export $JAVA_ARGS, maybe you can override $PATH to trick the script to run another program instead of the JVM, which could be a program that simply writes its arguments somewhere.