I have a third party application which includes a suite of DLL libraries that provide access to the application's data and commands.
Using Java, I want to access these DLLs in order to retrieve some specific data and write it to a file.
While similar questions to this have been asked before, I haven't found any that have helped me (I'm an absolute beginner at Java). I suspect this can be done with
JNA but need some guidance. It might be beyond my novice ability but I want to try.
There are several DLL files I need to access, each of which contain multiple libraries, which provide access to objects offering various functionality.
I need to gain access to these DLLs, instantiate objects from them, and gain access to the methods and variables provided. Is there a relatively easy Java solution that anyone knows of?
Thanks
EDIT: I've added example J++ code illustrating what I need to do in Java. J++ would firstly require creating COM wrappers for each of the required DLL files.
import dll1.*;
import dll2.*;
import dll3.*;
import com.ms.com.*;
public class Class1 {
public static void main(String[] args) {
// Create an application object
dll3.Application app = new dll3.Application();
// Use the getDataManager() method on the application
// object to get the DataManager object (which in turn is
// used to create the price object)
DataManager dm;
try {
dm = app.getDataManager();
} catch (Exception e) {
System.out.println(e);
return;
}
// Create the price data object using the CreateOb method of the
// DataManager object
PriceOb dp = (PriceOb) dm.CreateOb("Price");
// Set the requests parameters and make the request
dp.setVar1("abc");
dp.setVar2("xyz");
dp.Request();
Related
1). I know how to access the java fields and object in beanshell from my question Use java class fields in beanshell. However, it is not so clean way to implement as I need to first set the java variable in beanshell and then I can use it. However, in Jmeter it provides very clean way of using maps in beanshell similar way as we do in java, but JMeter has developed it's know library (class) which helps to access get/put methods for maps. I want to achieve similar way to access Map in beanshell.
I have checked JMeter for more information and I want to know that, I have created user define variable temp and assign value error, now in BSF process I just write a line vars.put('Name','temp Value') and it has updated value for temp variable. So, the question is I have not created JMeterVariables object vars but still beanshell allows to update values in map without setting any values as mention in your answer. I want to know how this works, need more depth information.
2). I have created my own class in java and in beanshell I am importing this class but it is giving Command not found: BSClass() below is the entire code
Java class
package test;
public class BSClass {
public void BSCMethod(){
System.out.println("I am from BSClass method BSCMethod");
}
}
sample.bsh
import test.BSClass;
c=BSClass();
c.BSCMethod();
print("I am from BeanShell Script");
Calling sample.bsh file java class
package test;
import java.io.FileNotFoundException;
import java.io.IOException;
import bsh.*;
public class DynamicVariable {
public static void main(String[] args) throws FileNotFoundException, IOException, EvalError {
new bsh.Interpreter().source("\\src\\test\\sample.bsh");
}
}
Note:
I don't need help in JMeter, it is to use in core java and beanshell.
All the files are in my project.
BSClass.class is under bin folder of my project
I would appreciate your inputs
In Beanshell you can add any Object you want including a Map
In JMeter, JMeterVariables is special implementation of Map that is added to Beanshell Interpreter before evaluate and also special Object as JMeterContext is added which even includes JMeterVariables inside. Code:
JMeterContext jmctx = JMeterContextService.getContext();
JMeterVariables vars = jmctx.getVariables();
try {
bshInterpreter.set("ctx", jmctx);//$NON-NLS-1$
bshInterpreter.set("Label", getName()); //$NON-NLS-1$
bshInterpreter.set("prev", jmctx.getPreviousResult());//$NON-NLS-1$
bshInterpreter.set("props", JMeterUtils.getJMeterProperties());
bshInterpreter.set("vars", vars);//$NON-NLS-1$
In your case with map you can do similar as you describe in comment:
bshInterpreter.set("myMap", javaMyMapObject);"
Then in Beanshell get the specific key from map:
myMap.get("aField");
To create class you should use new keyword, call:
c= new BSClass();
instead of c=BSClass();
If you create your own class, Class should be inside jar in relevant package .
The jar should be located in lib folder and not in bin folder, see JMeter's getting started:
Any jar file in such a directory will be automatically included in
user.classpath, jar files in sub directories are ignored. The given
value is in addition to any jars found in the lib directory. All
entries will be added to the class path of the system class loader and
also to the path of the JMeter internal loader.
I was hoping for someone to explain this item since I might be getting this wrong:
I was reading about Java Agent Instrumentation which says that the agent can start after VM startup. So if I want to dynamically replace some class (without brining down the app) is this what I am going to go for using agent-main? Or do I need to do something more here?
I know people might ask "Are you talking about JRebel" - not really because I want to do something simple and JRebel is an overkill.
instrument docs - Java docs for Instrumentation
I understand all the instrumentation overrides, but I am slightly confused how I can hook this agent with -agent argument after the app has started.
First your agent class needs to specify an agentmain method like:
public class MyAgent {
public static void agentmain(final String args, final Instrumentation inst) {
try {
System.out.println("Agent loaded.");
} catch (Exception e) {
// Catch and handle every exception as they would
// otherwise be ignored in an agentmain method
e.printStackTrace();
}
}
}
Compile it and pack it inside a jar-file for example. If you choose the jar-variant then it must specify the Agent-Class key in its manifest-file (MANIFEST.MF). It points to the class implementing the agentmain method. It could look like:
Manifest-Version: 1.0
Agent-Class: package1.package2.MyAgent
If it is located inside those packages, as an example.
After that you can load the agent via the VirtualMachine#loadAgent method (documentation). Note that the mechanism used by those classes are part of the Attach library of Java. They decided, as most users don't need it, to not directly add it to the systems path but you can just add it. It is located at
pathToYourJDKInstallation\jre\bin\attach.dll
And it needs to be somewhere where the system property java.library.path is pointing at. You could for example just copy it to your .../Windows/System32 folder or adjust the property or stuff like that.
As an example, if you want to inject an agent-jar inside another currently running jar, you could use a method like this:
public void injectJarIntoJar(final String processIdOfTargetJar,
final String pathToAgentJar, final String[] argumentsToPass) {
try {
final VirtualMachine vm = VirtualMachine.attach(processIdOfTargetJar);
vm.loadAgent(pathToAgentJar, argumentsToPass.toString());
vm.detach();
} catch (AttachNotSupportedException | AgentLoadException
| AgentInitializationException | IOException e) {
System.err.println("Unable to inject jar into target jar.");
}
}
With the same technique you can inject dll-libraries (if they implement the corresponding agent-methods via the native agent interface) into jars.
Actually, if that helps you, I have written some small library for that kind of stuff some time ago. See Mem-Eater-Bug, the corresponding class is Injector.java and the whole project has a small Wiki.
It has an example showing how to use that technique to manipulate a SpaceInvaders game written as Java application.
So apparently you want to reload classes at runtime. Such that your project can react to changes of the code without restarting.
To achieve this you need to prepare your project and write a very clean architecture, it involves using interfaces, factory-patterns, proxy-patterns and a routine that checks for updates and then destroys and rebuilds all current objects.
Unfortunately this might not be an easy task, but it is doable, depending on the size of your project and the amount of code that should react dynamically to changes.
I found this article helpful, let me explain how it works. You can easily load a class with ClassLoader.loadClass(...) and you can also use that to reload a class, very easy. However at the time you have compiled your code classes are some kind of hardwired already. So your old code will continue to create instances of the old classes although you have reloaded the class.
This is the reason why we need some kind of architecture that allows exchanging the old class with the new class. Also it is pretty obvious that current instances of the old class can not automatically be transferred to the new version as everything could have changed. So you will also need a custom method that collects and rebuilds those instances.
The approach described in the article uses an Interface instead of an actual class in the first place. This allows to easily exchange the class behind that interface without breaking the code that uses the interface.
Then you need a factory where you ask for instances of that Interface. The factory can now check if the underlying class-file has changed, if so it reloads it and obtains a reference to the new class version. It can now always create an instance of the interface which uses the up-to-date class.
The factory, by that, is also able to collect all created instances in order to exchange them later, if the code base has changed. But the factory should reference them using WeakReference (documentation), else you have a big memory leak because the Garbage Collector would not be able to delete instances because the factory holds references to them.
Okay, now we are able to always obtain up-to-date implementations of an Interface. But how can we easily exchange existing instances. The answer is by using a proxy-pattern (explanation).
It is simple, you have a proxy class which is the actual object you are working with. It has all the methods of the Interface and upon calling methods it simply forwards to the real class.
Your factory, as it has a list of all current instances using WeakReference, can now iterate the list of proxies and exchange their real class with a new up-to-date version of the object.
Existing proxies that are used all around your project will now automatically use the new real version as the proxy itself has not changed, only its internal reference to the real target has changed.
Now some sample code to give you a rough idea.
The interface for the objects you want to monitor:
public interface IExample {
void example();
}
The real class, which you want to rebuild:
public class RealExample implements IExample {
#Override
public void example() {
System.out.println("Hi there.");
}
}
The proxy class that you will actually use:
public class ProxyExample implements IExample {
private IExample mTarget;
public ProxyExample(final IExample target) {
this.mTarget = target;
}
#Override
public void example() {
// Forward to the real implementation
this.mRealExample.example();
}
public void exchangeTarget(final IExample target) {
this.mTarget = target;
}
}
The factory you will mainly use:
public class ExampleFactory {
private static final String CLASS_NAME_TO_MONITOR = "somePackage.RealExample";
private final List<WeakReference<ProxyExample>> mInstances;
private final URLClassLoader mClassLoader;
public ExampleFactory() {
mInstances = new LinkedList<>();
// Classloader that will always load the up-to-date version of the class to monitor
mClassLoader = new URLClassLoader(new URL[] {getClassPath()}) {
public Class loadClass(final String name) {
if (CLASS_NAME_TO_MONITOR.equals(name)) {
return findClass(name);
}
return super.loadClass(name);
}
};
}
private IExample createRealInstance() {
return (IExample) this.mClassLoader.loadClass(CLASS_NAME_TO_MONITOR).newInstance();
}
public IExample createInstance() {
// Create an up-to-date instance
final IExample instance = createRealInstance();
// Create a proxy around it
final ProxyExample proxy = new ProxyExample(instance);
// Add the proxy to the monitor
this.mInstances.add(proxy);
return proxy;
}
public void updateAllInstances() {
// Iterate the proxies and update their references
// Use a ListIterator to easily remove instances that have been cleared
final ListIterator<WeakReference<ProxyExample>> instanceIter =
this.mInstances.listIterator();
while (instanceIter.hasNext()) {
final WeakReference<ProxyExample> reference = instanceIter.next();
final ProxyExample proxy = reference.get();
// Remove the instance if it was already cleared,
// for example by the garbage collector
if (proxy == null) {
instanceIter.remove();
continue;
}
// Create an up-to-date instance for exchange
final IExample instance = createRealInstance();
// Update the target of the proxy instance
proxy.exchangeTarget(instance);
}
}
}
And finally how to use it:
public static void main(final String[] args) {
final ExampleFactory factory = new ExampleFactory();
// Get some instances using the factory
final IExample example1 = factory.createInstance();
final IExample example2 = factory.createInstance();
// Prints "Hi there."
example1.example();
// Update all instances
factory.updateAllInstances();
// Prints whatever the class now contains
example1.example();
}
Attaching an agent at runtime requires use of the attach API which is contained in the tools.jar until Java 8 and is contained in its own module starting from Java 9. The location of the tools.jar and the name of its classes is system-dependent (OS, version, vendor) and as of Java 9 it does not exist at all but must be resolved via its module.
If you are looking for an easy way to access this functionality, try out Byte Buddy which has a subproject byte-buddy-agent for this. Create a Java agent as you are used to it but add anAgent-Main entry where you would put your Pre-Main in the manifest. Also, name the entry method agentmain, not premain.
Using byte-buddy-agent, you can write a program:
class AgentLoader {
public static void main(String[] args) {
String processId = ...
File agentJar = ...
ByteBuddyAgent.attach(processId, agentJar);
}
}
and you are done.
I am writing a piece of software that needs licensing from government authority, there are more modules of the same kind (but doing different work - math algorithms). I need to secure that anytime anyone (mostly a representative of government authority) comes to this software and asks for it (via network), the checksum for that particular module is printed out. I am writing this server in Java. I looked into Serialization but it only cares about the data (attributes) in the object and not the object behaviour or other logical structure - which this absolutely needs to care about. Hence I need to access the .class from within the running jar file and perform a checksum on it. The current structure is like this:
abstract class Module {
public abstract void run();
public String chsum ();
}
abstract class SimpleGame extends Module {
/* not that important */
}
class GameX extends SimpleGame {
public void run() {
/* some magic */
}
}
And when needed, upon receiving the proper message the network stack might call something like:
GameX gx = new GameX();
String checkSum = gx.chsum();
My current progress got me nowhere, I tried to access the .class file but without any luck - it works only if it is not a jar archive. And I need to supply the Class instance which is not a dealbreaker but it sure is not that handy. If I could get an array of bytes containing the compiled .class file that would be more than enough - to perform a checksum on that is a piece of cake using MessageDigest
I know the difference between Static class loading and Dynamic class loading.
In general,we always use Static class loading only.Can anyone tell, under which situations we use Dynamic class loading??
Dynamic Class Loading allows the loading of java code that is not known about before a program starts. The Java model loads classes as needed and need not know the name of all classes in a collection before any one of its classes can be loaded and run.
For example :
Depending on user input you want to create only one object and there are hundreds of classes.
Then you don't need load all classes. You can create object at run time by dynamic class loading.
Code:
try {
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(in);
System.out.println("Enter Class Name: ");
String whatClass = reader.readLine();
Class exampleClass = Class.forName(whatClass);
Object ob = exampleClass.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
DYNAMIC CLASS LOADING
It allows you to build your applications so that key external dependencies are not compiled into the application source-code.
APPLICATIONS
JDBC
For example, in the JDBC case, it allows you to switch between different driver implementations, and (in theory) different database vendors without changing your source code.
PLUG-INS
Another use-case is when some supplier develops a generic form of an application with extension points that allow customers to "plug in" their own custom classes. The custom classes are typically loaded using Class.forName(...).
FRAMEWORKS AND CONTAINERS
A third use-case is application frameworks and containers which typically use Class.forName(...) under the hood to dynamically load the classes for application-specific beans, servlets, and so on.
OTHERS
A fourth use-case is where the application (or more likely an application library) has modules that are not used in a typical application run. By using Class.forName(...) internally, the application or library can avoid the CPU and memory overhead of loading and initializing large numbers of unwanted classes. (The Sun Swing libraries apparently do this to reduce application startup times, and I'm sure there are other examples.)
Refer Dynamic Class Loading
One common example is trivial JDBC programming. Dynamic classloading is used to load the driver class
If you see any code with Class.forName() then that is the example for dynamic loading
Generally speaking, whenever your program will use classes that aren't necessarily available at compile time. An example would be a plug-in system, where you could create new plug-ins without recompiling the original application.
When you are using reflection and creating new instances. You can always fetch new jar eg. via url and create object from it on runtime.
Most common case in Java are plugins and plugin like libraries like JDBC drivers.
Dynamic loading is a technique for programmatically invoking the functions of a class loader at run time. Let us look at how to load classes dynamically by using Class.forName (String className); method, it is a static method.
The above static method returns the class object associated with the class name. The string className can be supplied dynamically at run time. Once the class is dynamically loaded the class.newInstance () method returns an instance of the loaded class. It is just like creating a class object with no arguments.
A ClassNotFoundException is thrown when an application tries to load in a class through its class name, but no definition for the class with the specified name could be found.
Here is example of dynamic class loading:
import java.util.Scanner;
interface IRobot{
void start();
}
class Robot implements IRobot{
public void start(){
System.out.println("Starting robot...");
}
}
public class Hello{
public static void main(String[] args){
ClassLoader loader = Hello.class.getClassLoader();
try {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter class name to load: ");
String className = scanner.nextLine();
// Load the class dynamically.
Class cls = loader.loadClass(className);
IRobot obj =(IRobot) cls.newInstance();
obj.start();
scanner.close();
} catch (ClassNotFoundException e) {
System.out.println("Class not found");
} catch (Exception ex){
System.out.println(ex.getMessage());
System.out.println("Exception occured.");
}
}
}
I'm attempting to implement a package-scanning feature, similar to Spring's component-scan, for the Android framework I'm developing. Basically, I would like to be able to specify a base package, e.g. com.foo.bar and retrieve all Class instances that have a particular annotation. I don't want to have to register every component with my framework as that would defeat the purpose of the auto scanning.
Based on my research, it seems that it's not possible with Java to retrieve resources given a package name using reflection. However, I briefly looked into the Reflections framework, and I'm wondering if there is an Android-compatible equivalent. If not, perhaps there is a slightly less obvious way to accomplish what I want to do.
I looked into the Spring source a bit to see how they achieved this, but I don't think what they are doing would work within the Dalvik runtime.
Update
Currently, the below code has been the best I can do to retrieve all classes that contain a specific annotation, but frankly it's a pretty poor solution. It makes some really unsafe assumptions about the ClassLoader plus it scans (and loads) all application classes.
public Set<Class<?>> getClassesWithAnnotation(Class<? extends Annotation> annotation) {
Set<Class<?>> classes = new HashSet<Class<?>>();
Field dexField = PathClassLoader.class.getDeclaredField("mDexs");
dexField.setAccessible(true);
PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader();
DexFile[] dexs = (DexFile[]) dexField.get(classLoader);
for (DexFile dex : dexs) {
Enumeration<String> entries = dex.entries();
while (entries.hasMoreElements()) {
String entry = entries.nextElement();
Class<?> entryClass = dex.loadClass(entry, classLoader);
if (entryClass != null && entryClass.isAnnotationPresent(annotation)) {
classes.add(entryClass);
}
}
}
return classes;
}
I wanted to find all the subclass at runtime.
So I've been looking for android class scanning.
This is my final code from what I gathered in web.
You will get the idea.
public static void findSubClasses(Context context, Class parent) {
ApplicationInfo ai = context.getApplicationInfo();
String classPath = ai.sourceDir;
DexFile dex = null;
try {
dex = new DexFile(classPath);
Enumeration<String> apkClassNames = dex.entries();
while (apkClassNames.hasMoreElements()) {
String className = apkClassNames.nextElement();
try {
Class c = context.getClassLoader().loadClass(className);
if (parent.isAssignableFrom(c)) {
android.util.Log.i("nora", className);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// android.util.Log.i("nora", className);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
dex.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I share the opinion of Joop Eggen and find his approach a good one. In Android I try to avoid the usual web app features which lead to a long lasting application start. I do not use reflection or package scanning.
But if you want to .... if I understand it correctly you want to have an annotation for a class. Instead of using annotations you could also use marker interfaces (to just have more possibilites).
1) Look at
Annotation: Java custom annotation and dynamic loading
Has an implementation in the question which just answers your question.
Annotation: Scanning Java annotations at runtime
Interface: Find Java classes implementing an interface
Interface: Is something similar to ServiceLoader in Java 1.5?
Interface: How can I get a list of all the implementations of an interface programmatically in Java?
Interface: Since the approach is expensive, maybe the ServiceLoader is a compromise between execution time and comfort, since it loads only the classes given in the services file. On the other hand if only classes with a certain interface are in your package then the ServiceLoader isn't that faster.
2) AndroidAnnotations
I would prefer the way AndroidAnnotations work (maybe an integration in AndroidAnnotations is the preferable way): It automatically adds an extra compilation step that generates source code, using the standard Java Annotation Processing Tool. So instead of runtime scanning you execute code based on the annotations generated during compile time.
I think the Bean/EBean annotation could work for you (only single class): https://github.com/excilys/androidannotations/wiki/Enhance%20custom%20classes
A scan-feature is not available, see this thread
3) Writing your own annotation processor
See APT (Annotation Processing Tool). The idea would be to generate a static function which returns a list of classes which are annotated, so that no class scanning is needed.
A very good ressource is http://javadude.com/articles/annotations/index.html
Take a look at Vogar's ClassPathScanner. It uses it to find test cases on the class path.
EDIT:
I found this issue in the Android issue tracker. It appears that ClassLoader.getResource(String) is 'working as expected', in that it returns null. This is expected because the DalvikVM does not keep the resources around after compiling. There are workarounds listed in the issue, but there may be another way to access the classes you desire.
Use the PackageManager to get a hold of an instance of ApplicationInfo. ApplicationInfo has a public field called sourceDir which is the full path (a String) to the location of the source directory for that application. Create a File from this String, and you should be able to navigate to your package within the source directory. Once there, you can use the method from my original answer to find the classes you are looking for.
String applicationSourceDir =
getPackageManager().getApplicationInfo(androidPackageName, 0).sourceDir;
/EDIT
You should be able to use the ClassLoader.getResource(String) to get a URL to your specific package (the passed in String being the package name you are interested in delimited by path separators rather than periods). With this URL you can then call getFile(), from which you can create a Java File to the package folder. Call packageFile.listFiles() from there, and you have your classes/subpackages.
Be recursive with the subpackages, and with the classes find the Class object using the static Class.forName(String) method.
In your java build process incorporate the class path scanning, generating injection data/code. This could then be ported too to Dalvik. It is even more efficient that dynamic scanning.