I have created a C++ dll for a java application. I have the dll working within the application if I launch it separately, which includes a very lengthy batch file to get all of the correct arguments. I would like to try an debug the dll that I created in Visual Studio 2010. I have tried putting the command line and arguments into the debugging property page in visual studio. Although I am not able to get the application to launch correctly.
The command line to launch the application looks like this assuming the application is ApplicationName...
start "ApplicationName" "C:\AppDirectory\jre\bin\javaw" -D sun.java2d.nodraw=true -Xms24m -Xmx128m -classpath "C:\AppDirectory\classes\;C:\AppDirectory\classes\iText.jar" ApplicationName
Any ideas on how to property setup the debug settings for this?
Any ideas on where I could find some documentation on this?
I would strongly consider the following:
If possible, structure the JNI such that the code which does the work knows nothing about JNI. Have it receive only native C++ stuff as arguments and return native C++ stuff as return values, and not call any JNIEnv functions.
Have a shim layer that has the actual implementations of the native methods in your Java classes. The shim layer will know how to call JNIEnv functions to extract the parameters, turn them into native C++ objects and pass them to the working code. Likewise, this layer will know how to turn the C++ objects back into Java objects. For example, if a worker function returns a std::string, the shim layer will know how to call JNIEnv functions to have the native method return a Java String back to the JVM.
I understand that things can't always be structured this way, but there are some nice advantages to it:
It will allow you to write a C++ program to drive the worker code directly. This can make it much faster and easier to test your code rather than having to manipulate your Java app into a state where it is using your code how you want to test.
You will be able to run just your code under a debugger, valgrind, memory profilers, etc. without having to run the whole JVM under the tool. This makes it much easier to pin down what memory may be being leaked, buffers overrun, etc. without being swamped in "noise" caused by JVM internal operations.
It is true that this approach means the shim layer isn't being tested. But since the shim layer is only translating objects between the Java world and the C++ world it is hopefully pretty simple and thus amenable to being testing in the context of the full Java app.
In my application I added logic that checks a command line option at startup and calls DebugBreak if the command line option was passed to it.
I did this because my application is often called in quite complex scripts and it was sometimes very hard or even impossible to launch the application from the debugger with the correct environment (path, environment variables, temporary files, ...) set by the script.
So, simply call DebugBreak (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms679297%28v=vs.85%29.aspx) if a specific command line option is passed to your DLL.
When the breakpoint goes off, the JIT debugger will show a popup in which you can start or attach your debugger.
Related
I'm just transitioning from Ruby to Java and debugging in Ruby was made much easier via the 'Pry' gem. You could place binding.pry anywhere in the code and upon running the app, the code would stop or 'freeze' at the binding.pry and allow you to manipulate variables, create new objects, return values, etc - essentially it dropped you into a playground environment at that given point in time.
Anything similar in Java?
Debugging is the way to go, if you are used to run IRB/pry/rails console in production then you need to get in the habit of changing your connection settings to production which is very dangerous but an option for a language that does not offer a REPL (read eval print loop) console.
Setup a Java class just to be the entry point of the code you want to debug then add the breakpoints and run it in Debug mode. Every time you need to debug something else, change that entry point class to do something else.
You may as well just use breakpoints in your routes/endpoints, you add a breakpoint to a route and you trigger an API call either with curl, postman or any HTTP client that triggers that route.
From what I read, there are a couple of ways to run java files in a node.js application. One way is to spawn a child process: (the java code is packaged with dependencies in an executable jar.)
var exec = require('child_process').exec, child;
child = exec('java -jar file.jar arg1 arg2',
function (error, stdout, stderr){
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if(error !== null){
console.log('exec error: ' + error);
}
});
The other way is to use the java - npm module (link), a wrapper over JNI (this will let me create objects, set and get attributes, run methods).
In a production environment, when I want my node.js (Express) server to call a java program (it just saves an image to the local directory), please advise me on which would be the better way to accomplish this (in terms of best practices). Also, there is a long list of arguments that I need to pass to the main class and doing that on the command line is a bit of a struggle. Should I make the java program read from an input file instead?
1) If you use exec, you will run an entire program, whereas if you use a JNI interface, you'll be able to directly interact with the libraries and classes in the jar and do things like call a single function or create an instance of a class. However, if you don't need anything like that, I think using exec is far simpler and will also run faster. Sounds like you just want to run the Java application as a standalone process, and just log whether the application finished successfully or with errors. I'd say it's probably better to just use exec for that. Executing a child process this way is also far better for debugging, debugging JNI errors can be very difficult sometimes.
2) As for whether or not to read arguments from a file, yes, it's usually better to read from some sort of file as opposed to passing in arguments directly. It's less prone to human error (ie. typing in arguments every time), and far more configurable. If someone like a QA engineer only needs to edit a config file to swap out options, they don't need to understand your entire codebase to test it. Personally I use config files for every Java program I write.
You can use deployment toolkit and run the jar through jnlp. https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/deployment_toolkit.html
Advantage of running jars through jnlp is the ability to pass parameters from javascript to your jar. In this way you can dynamically customize your java program.
For this kind of problem you'd want to approach it in the following way:
Is there a decent way to run processes with arguments in my language/framework
Is there a decent way to deal with the programs output?
From experience, a decent way to deal with arguments in a process is to pass them as an (string) array. This is advantageous in that you do not have to resort to unnecessary string interpolation and manipulation. It is also more readable too which is a plus in this problem setting.
A decent way to deal with output is to use a listener/event based model. This way, you respond appropriately to the events instead of having if blocks for stderr and stdout. Again, this makes things readable and let's you handle output in a more maintainable manner.
If you go a bit further into this, you will also have to solve a problem of how to inject environment variables into your target program. As an example, you might want to run the java with a debugger or with less memory in the future, so your solution would also need to cater for this.
This is just one way of solving this kind of problem. If node is your platform, then have a look at Child Process which supports all of these techniques.
We can run the whole java project by making .jar file of it and run it using the command in the shell and run that shell file. In order to run java code from nodejs project as we know project could be a mix of java, js modules.
Call exec() function in node to create a child process to execute the shell file having a command to run .sh file and can also pass some argument in it from use.eg;
let fileName = 'someFile.txt';
let userName = 'Charlie Angle';
exec(`sh run.sh --context_param
paramFilePath="./storage/${fileName}" --context_param userName="${userName}"`, (error, stdout, stderr) => {// Some code based on execution of above command})
You can simply call a java command , with classpath & arguments, using module node-java-caller, it embeds the call to spawn and will also automatically install java if not present on the system
https://github.com/nvuillam/node-java-caller
I have been using Matlab for years and like the way debuging in it, all values are stored in memory, when you need check one, just type in command window.
However, in C++ and Java, those data not printed or given in console would not be able to see after execution. Is there some developing environment that can enable me to debug Java and C like Matlab?
Thanks,
Jason
I have been using Java for years.In java ide like IDEA,Eclipse,Netbeans,you can put a line breakpoint to see the values in memory.
I assume you are referring to debugging mex files (C++ compiled Matlab functions).
Even in your C/C++ modules, you can still access Matlab's environment (variables available from the command line). What I usually do is write temporary variables from the mex C code so I can later analyze the data and understand the inner working of the function.
The C function mexPutVariable may be used with the first argument "base" (or "caller") to create a Matlab array that is available from the command line after the mex has finished processing.
I have an strange issue.. I have source code of JAGS software which I can compile in solaris i86 and it generates an executable file.. and it was working fine... now issue is
I want to call this executable file from JAVA and wish I was able to do that..
Now I want to use the same source code without executable file and want to create an shared object which can be triggered from java usin JNI.
Is it possible to modify the make file and generate a shared object instead of an executable file?
You can call an executable from java. Just a matter of:
String[] cmd = { "/path/to/program", "arg1", "arg2" };
Process proc = Runtime.getRuntime().exec( cmd );
You can then use proc to communicate with the command via standard I/O streams, and to wait for it to finish.
Now if you wanted to go down the JNI path you will need to write some additional code to act as the JNI layer between the java and C. This layer is responsible for keeping track of the allocated C memory and converting between C data types and Java datatypes. This layer would then be able to call functions in your other source code (but probably not the main function). Then you need to modify/create a makefile which links your new JNI layer source code with the source code you already have into a .dll/.so. You then need to write the java class(es) that sit atop your JNI layer.
Which approach you choose really depends on what you want the native code to do, and how much interaction you need with it.
I have a Java program that is mostly GUI and it shows data that is written to an xml file from a c++ command line tool. Now I want to add a button to the java program to refresh the data. This means that my program has to call the c++ functionality.
Is the best way to just call the program from java through a system call?
The c++ program will be compiled for mac os and windows and should always be in the same directory as the java program.
I would like to generate an executable can the c program be stored inside the jar and called from my program?
If you have access to the code and want an 'interactive' experience with the external program (e.g., make call, get results, make additional calls), investigate JNI, which allows you to call C or C++ code from a Java application by including & linking JNI juice to your C or C++ app with .
See:
http://en.wikipedia.org/wiki/Java_Native_Interface
http://www.acm.org/crossroads/xrds4-2/jni.html
If you really just need a "launch app and get results" sort of solution, check out Runtime.exec(), which lets you launch an external program & capture its output.
See:
http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1
http://www.rgagnon.com/javadetails/java-0014.html
Assuming no better communication method is available (SOAP, ICE, Sockets, etc), I'd call the executable using Runtime.exec(). JNI can be used to interface directly, but I wouldn't recommended it. No you can't put an executable in the jar. Well you can, but you can't run it, since the shell doesn't know how to run it.
You may also want to look at the Java Native Access API (JNA).
To answer your final question, you can't run an executable from within your jar.
However, you can store it within your jar and extract it to a temporary directory/file prior to running it (check for its presence the first time and extract if necessary). This will simplify your distribution somewhat, in that you only have the jar to distribute, and ensures that you're running an executable that matches your jarred Java code.