Thread-safe use of GraphViz library via JNI - java

I am trying to use GraphViz 2.40.1 under Linux in a REST service that lays out graphs. The service is a Java Spring Boot application. My current approach is to load shared libraries into my JVM, and call native code via JNI, using functions from libraries cgraph and gvc. I'd like to do everything in-memory and avoid file I/O. But I have read the following caveat in the GraphViz lib guide, printed in bold face at the end of section 1: "N.B. Using Graphviz as a library is not thread-safe."
I am seeking help about the consequences I should draw from that statement. No details are given. For example, I can imagine that functions that keep mutable state about errors that have occurred in graph parsing are not thread-safe, but I'm not using these. I only use the following functions: agmemread and agclose from cgraph, and gvContext, gvParseArgs, gvLayout, gvRenderData, gvFreeRenderData, gvFreeLayout, gvFreeContext from gvc. I am caching nothing in Java, local vars and method params only. Would such a use of the library be thread-safe?
If not, does the non-thread-safety only affect uses of single functions, not across functions? So would it be enough to make my Java native methods static synchronized? Or would I have to synchronize on every REST request?
Alternatively, I could fork a new OS process for each request and do file operations with GraphViz's dot program with Runtime.exec().
What approach would scale best?

Related

How to retrieve real-time data from an existing Java application without access to source code?

Update: Jun 10, 2022
I have successfully been able to create a demo application with AspectJ integration that could extract variables from the demo application. It was quite a hassle since there's a bit of trouble going on with Eclipse AJDT integration.
I was able to use CLI Java and ajc (AspectJ compiler) to achieve binary weaving into my demo application.
Original Question:
I am trying to retrieve real-time data from a running Java application and push it into an API I have on a server.|
I have no access to the source code of the running application; I only have the Jar file. I have tried decompilation into .java files; however, due to the scale of the app, I was not able to fix all of the missing access$000 function calls.
Is there a certain approach I should use when retrieving real-time data from an existing Java application? Has that been done before? Am I missing something that I am not aware of?
Any help is appreciated.
This is big challenge obviously. If you can glean enough understanding of how the program works from decompiling and reading log files to target some methods where you suspect there's data of interest to your API, then I would read up about Aspect Oriented Programming [AOP] and use those tools.
With AOP you can modify the classes in the jar file at runtime as its loaded by the JVM and access the classes.
For example: You can gather data from:
fields within the class that owns a method
parameters passed to a method
value returned from a method
Once you gather the data, you can also insert calls to your API.
Here's a place to start - https://www.baeldung.com/aspectj .

Java calling python function with tensorflow graph

So I have a neural network in tensorflow (python2.7) and I need to retrieve its output using Java. I have a simple python function getValue(input) which starts the session and retrieves the value. I am open to any suggestions. I believe Jython wont work cause tensorflow is not in the library. I need the call to be as fast as possible. JNI exists for Java calling C so can I convert with cython and compile then use JNI? Is there a way to pass the information in RAM or some other way I haven't thought of?
In Python, save the model (using saver.save) and the graph (using tf.train.write_graph).
In Java, use the org.bytedeco.javacpp-presets library to instantiate a GraphDef from the saved protobuf file and pass in your input features and get the output features within a Session.
See https://medium.com/google-cloud/how-to-invoke-a-trained-tensorflow-model-from-java-programs-27ed5f4f502d#.4su1s26fz for example code.
I've had the same problem, Java+Python+TensorFlow. I've ended up setting up a simple http server. If that's too slow for you, you can shave off some overhead by employing sockets directly.
Encapsulate your calling for TensorFlow into a script.py and then:
Process proc = Runtime.getRuntime().exec("python script.py");
Not sure whether it solves your case.

Spark Model to use in Java Application

For analysis.
I know we can use the Save function and load the Model in Spark application. But it works only in Spark application (Java, Scala, Python).
We can also use the PMML and export the model to other type of application.
Is there any way to use a Spark model in a Java application?
I am one of the creators of MLeap. Check us out, it is meant for exactly your use case. If there is a transformer you need that is not currently supported, get in touch with me and we will get it in there.
Our serialization format is solely JSON/Protobuf right now, so it is very portable and supports large models like RandomForest. You can serialize your model to a zip file then load it up wherever.
Take a look at our demo to get a use case:
https://github.com/TrueCar/mleap-demo
Currently no, your options are to use PMML for those models that support it, or write your own framework for using models outside of Spark.
There is movement towards enabling this (see this issue). You could also check out Mleap.

JRuby DSL encapsulation, exclude standard library

I'm trying to make a Java program that allows users to do some limited scripting with a Ruby DSL that I've written. The script the user writes is saved to a Proc object in JRuby. The problem arises in that the user can still access methods that are standard to Ruby, such as File.new, or creating classes, or basically messing with other internal logic of the program or computer.
Is there a way to limit the user's script to only the constraints of the DSL, using JRuby or Ruby or even Java? Or at least to remove the user's access to certain classes?
Since you're running under JRuby, you can use a Java security policy (policy file documentation) to prevent users from being able to do things like file or network I/O. Of course, this will keep your code from having those capabilities, too! You can whitelist code by jar URI or by jar signature, so one tactic is to create a "hull" of trusted code that strongly validates its input, package it in its own jar, trust it, and use it exclusively for your own code. Doing this right gets complicated fast (have an extensive test suite!), but it can be done.
To have explicit control over the namespace available to your DSL, you can use BasicObject. It doesn't mix in Kernel or any of the other things available in the standard Ruby namespace. This doesn't give you security, though, because users can still use ::File directly or include ::Kernel to get it all back!

How to analyze method calls and objects of other classes used in a java class programmatically

i need to detect if a class relies on another class programatically,to detect inappropriate intimacy code smell(i want to analyze other java programs ,using my program).Any directions on
how to achieve this will be a great help.
And
How to identify all the objects created in a java program?
How to identify all the called methods in a java program?
Any help would be appreciated.
You might want to use what's already there instead of building something yourself. Especially if you're not very familiar with the internals of Java and the JVM.
Have a look at JDepend: http://clarkware.com/software/JDepend.html
Use a profiler as JConsole or VisualVM. With the use of profilers you can pretty much see everything that happens at runtime.
One way i think of is using logger, Put some log statement in the construct and in the methods you want to monitor. So through logs you can find out the objects created and methods accessed
I have found very useful the ObjectWeb asm-all Java bytecode manipulation and analysis library, also known as asm-all.jar
It allows you to convert any *.jar application into equivalent XML file. You can fully inspect the application structure, change it in the XML format and convert back into *.jar file
In order to use the XML files you'll need to understand what it contains. Oracle's The Java® Virtual Machine Specification is very good reference to start with
BTW: one thing you can do with this tool is to instrument the bytecode so that it creates runtime profiling information - which methods were called and by whom (as suggested by #upog)

Categories