How to use .Net Maui windows platform to run IKVM and read and run jar file on the run? - java

I have a java library project that is written as a library for another java project. Inside that library project there are hundreds of classes each of them supplying different kind of methods , but each if them is inheriting from a parent class.
Each of the class inside the java Library has a constructor that define some unique value for the class itself.
Now I want develope a C# application preferably using .Net Maui, so that I can read the library jar file and execute the constructer for each of the child class, and read those unique value. The unique value field are defined in the parent class as a protected field, but there is a public getter in the parent class that can be used to retrieve that unique value.
The jar file will be compiled using JDK 1.8.0 by other people.
Noted that there will be many jar files because different products will have different java library, so I need to allow user to input the jar file into my Maui project during runtime from filepicker or something similar.
The endpoint is that from my Maui project I can input any jar file, check all available classes, execute their constructor, then execute the getter for the unique value and get what is their unique value for each class.
I am not very familiar with Java, but quite good with C#. Is this is possible, and is there any sample syntax that i can use for? I had been searching and trying for few days without any success, since there are lacks of reference on the Syntax in C#.
Thank you in advance.

Related

See result of System.loadLibrary/ the defined methods and classes?

I have an .so file that I successfully integrated into android studio and I can load the file by calling System.loadLibrary.
Is there a way I can see what methods and classes I can use now with this library loaded?
Depends on how the library maps Java methods to native function pointers: it can do one or both of the following:
Dynamic symbols that start with Java_ are mangled names for the class and method name.
If the code uses RegisterNatives system call you will have to put a breakpoint on env->RegisterNatives and look at the surrounding code/arguments.

Java Bytecode Manipulation Without External Library

Libraries such as ASM, BCEL, Javaassist and AspectJ are all capable of runtime bytecode manipulation but how do they achieve this?
I have done some basic bytecode manipulation using ASM before but i don't understand how it works. Is the Java Agent executed in the JVM before the remainder of the program, allowing for ASM to load the compiled classes and edit them before they are executed by the JVM?
If so, is it possible to perform java bytecode manipulation without using an external library like ASM and loading the compiled class files with an BufferedReader and writing a custom parser etc. for example?
These libraries settle on standard Java APIs which, of course, you can also use yourself without these libraries.
First of all, Java class files are just sequences of bytes in a well defined format, as specified in JVMS §4, The class File Format. The primary task of the mentioned libraries is to provide tools for processing byte sequences in this format. The second is about getting the definitions of existing or exporting modified or newly created classes.
There are two different way of dealing with the second task. One is to read compiled classes from persistent storage like file systems or jar files, etc. and writing them back to these storage while the particular code is not running, like build and deployment tools do. This should be trivial, as it just boils down to reading and writing bytes.
The other is to manipulate classes at runtime, which can be done by Java Agents via the Instrumentation API. It offers mechanisms for intercepting classes at loading/definition time before their first use, but also redefinition of classes. The latter can’t change them freely, currently, it has to retain all field and method declarations, so it can be mainly used to change the executable code of the methods.
If you want examples for class file processing without additional 3rd party libraries, there are some answers on Stackoverflow
Extract the class name from a class file
Find all class dependencies
Parse the constant pool
Iterate over all instructions of a method
Of course, these examples are only single-purpose code or sketches. If you expand them to something more general or useful, you will soon end up at basically re-implementing these libraries.
Class files are just a sequence of bytes, the format of which is specified in The Java Virtual Machine Specification. BufferedReader is for text files so you'd want BufferedInputStream, but the format is quite complicated.
You can load manipulated class files as if they were generated by javac. You can also load them dynamically with java.net.URLClassLoader.newInstance or similar. Java Agent allows modification of class files as they are loaded, either through a Java or a native interface (the latter being necessary if you want to modify classes the are loaded before classes that load classes).
Recently java development group at Oracle announced a new JEP( Java enhancement proposal) for class file manipulation. Now we will not need any additional libraries.
https://openjdk.org/jeps/8280389

Android How do I use the same native library (.so) for multiple projects and classes?

I am making a android project with some native code . running javah results in header files which contain function prototypes with fully qualified java class name in their names. I assume this means that those functions and headers are generated to be called only by the java class which was used to create them using javah.
How do I go on making a native lib that I can use with other classes as well as other projects. Like say I made a library that has a function that I want to use in all my projects then how would I build it so that I can use just the .so file each time without recompiling it for the project. I think we call this dynamic library?
Is it possible? or do I have to create seperate jni headers for each class and then reuse the remaining c/c++ code?
if you want to reuse your native library from various Java projects, you should directly bundle your native library with a Java class that is independent from your initial project.
This way you'll be able to distribute it as an Android Library Project, and use it from your various classes and projects.

Creating java executable using JNI?

I am trying to create executable under windows platform for Java program using JNI ,C/C++ and invocation API, I have already created jar file for my program which includes all dependencies. I want to embed it in exe file, I was successful in running simple main class(present in file system) using JNI invocation API, I am planning to add jar file as resource in C/C++ program. But I don't know how do I run that jar file , One option is create temporary jar file on file system and run it using java, But I do not want to expose my jar file to everyone for security reasons, How can I run jar file on the fly using JNI ?
Compiling Java to an executable with GCJ does not work all the time, there are limitations as far as using reflection and other items such as UI classes, Look at this page.
If you convert you Java Code to a library or simply another module then you could link to it and simply run it without the need for a JVM.
My initial reaction was that I would be shocked if you could get this to work and have it be performant. But then I started thinking about it, and maybe you could pull this off using a custom class loader. If you embed the jar in the exe as a resource, it would be exactly the same as having the jar bytes be present at a particular offset in any file (whether an exe or not).
So, here's a potential strategy: implement a custom class loader that accepts the exe path and offset of the jar resource in that file. This would use a custom version of ZipFile that uses a fixed index offset for it's reads (unfortunately, it isn't going to be possible to use ZipFile itself - but if you grab the source of ZipFile it should be pretty obvious where you'll need to add the offset).
There is a bootstrapping issue here (how do you load the custom class loader?) - but I think it might be possible to do that from the JNI side. Basically you'd store the .class file for the loader as a separate resource in the exe, load it fully into memory then construct it using JNI calls. That will be a hassle, but it's just for one class, and then you can let the Java runtime take over the rest.
Sounds like an interesting project (Although, as others are pointing out, there isn't much security in what you are doing... I suppose that you could encrypt the embedded jar and add decryption code to the classloader, but you've kinda got to decide how far you want to take this thing).

Possible ways to abstract away hard-coded path-names for properties file in java app

I'm trying to bind in a third party app to our project but have discovered that the unix paths of their property files have been hard-coded into several classes. It is probably possible to make minimal changes to their setup, so my question is: what are the possible (and quickest) ways to achieve this? The third party app uses neither ant nor spring, but just a build script that compiles the code into a .jar that is called from the command line.
You could read the properties files as resources. Then you only have to put the directories containing these files into your classpath.
You haven't actually said what you want to achieve. Would your application determine some paths and pass them to third party app via an API? Would something in your environment (for example a command line argument) specify the location of the files?
I would first refactor their code so that I know for certain that any hard coded strings are held in one defined place. So if for example they have
readProperties("/usr/thing/propertyFileXxx.txt");
or
static final String PROPERTY_XXX = "/usr/thing/propertyFileXxx.txt";
readProperties(PROPERTY_XXX);
I would first consolidate to a single accessor for the properties
readProperties(PROPERTY_XXX_ENUM);
So now we have a well-defined single piece of code that determines where to obtain the properties of each type and a specific list of the types of properties.
Then we need some controllable way to define the set of property files to be used at run-time. I have used the idea suggested by #tangens of loading the properties as resourcees from a specific directory added to the classpath.

Categories