Help using ClassLoaders - classloader

I'm trying to get this thing with using different ClassLoaders to work with no success and I'm getting kind of desperate. What I'm trying to do is to launch 2 different instances of a 3rd party program that was created with several static attributes and therefore can't just be instantiated twice in my code. I've been advised to use different ClassLoaders to load the .jar file, though I don't really know how to do this. Could I maybe get some pointers on where I could start?
I also need to pass an object of my own program to this program instance and I also have no idea of how I could do this...
Thanks in advance for the help,
Andre
PS: This whole discussion started in the java forums, so there's a more detailed description of what I need to do and why I need to do this. The advice I'm referring to in this post was from malcommmc:
Another approach might be to run the
whole system in one JVM, but create a
new classloader for each instance of
the 3rd party code and make sure that
the classes containing the offending
statics are only loadable by these new
class loaders. Under these conditions
the JVM can support multiple copies of
the same class, providing the FQN is
unique within a class loader.
In this case run each instance as a
separate Thread, and set the thread's
context class loader to point to the
relevant class loader.
Presumably the object you are
proposing to pass is specified with
some interface or abstract class known
to the 3rd party app. You need that
interface to be known to the system
class loader, i.e. on the class path,
but the principal classes of the 3rd
party app must not be on the
classpath, but be accessed as a jar
referenced by a URLClassLoader.

This was already solved in the Java forums - link provided in the question

Related

Is there a way to implement dynamic factory pattern in c++?

The DYNAMIC FACTORY pattern describes how to create a factory that
allows the creation of unanticipated products derived from the same
abstraction by storing the information about their concrete type in
external metadata
from : http://www.wirfs-brock.com/PDFs/TheDynamicFactoryPattern.pdf
The PDF says:
Configurability
. We can change the behavior of an application by just changing its configuration
information. This can be done without the need to change any source code (just change the descriptive information about the type in the metadata repository) or to restart the application (if caching is not used – if caching is used the cache will need to be flushed).
It is not possible to introduce new types to a running C++ program without modifying source code. At the very least, you'd need to write a shared library containing a factory to generate instances of the new type: but doing so is expressly rules out by the PDF:
Extensibility / Evolvability
. New product types should be easily
added without requiring neither a
new factory class nor modifying
any existing one.
This is not practical in C++.
Still, the functionality can be achieved by using metadata to guide some code writing function, then invoking the compiler (whether as a subprocess or a library) to create a shared library. This is pretty much what the languages mentioned in the PDF are doing when they use reflection and metadata to ask the virtual machine to create new class instances: it's just more normal in those language environments to need bits of the compiler/interpreter hanging around in memory, so it doesn't seem such a big step.
Yes...
Look at the Factories classes in the Qtilities Qt library.
#TonyD regarding
We can change the behavior of an application by just changing its configuration information.
It is 100% possible if you interpret the sentence in another way. What I read and understand is you change a configuration file (xml in the doc) that gets loaded to change the behaviour of the application. So perhaps your application has 2 loggers, one to file and one to a GUI. So the config file can be edited to choose one or both to be used. Thus no change of the application but the behaviour is changed. The requirement is that anything that you can configure in the file is available in the code, so to say log using network will not work since it is not implemented.
New product types should be easily added without requiring neither a new factory class nor modifying any existing one.
Yes that sounds a bit impossible. I will accept the ability to add ones without having to change the original application. Thus one should be able to add using plugins or another method and leave the application/factory/existing classes in tact and unchanged.
All of the above is supported by the example provided. Although Qtilities is a Qt library, the factories are not Qt specific.

Integrate python scripts in c++ app

I need to extend my c++ app with python scripts but I'm unsure which interface library I should use. The basic communication is: c++ app registers some class methods to the script (so that they could be loaded as module in the script), then calls a specific function in the python script. The script should then perform its task while being able to call the c++ methods. When the script has finished, the c++ app should be able to use the return value of the script (e.g. as a std::list).
From what I've read boost.python is pretty powerful and considering the fact that I already use boost, it seems the way to go. But in the documentation, I have not seen a way to expose class methods (static or not) to the python script.
Is this possible? How can I do that?
Edit:
Ok, I think I should have been a little more specific, sorry. I already know about how to import python libraries etc. into my c++ code and I've taken a look into the boost documentation regarding embedding but didn't got what I was looking for.
For clarity, this is the workflow in my scenario:
C++ app starts running
At some point, a C++ class needs support from a specific python script which is located somewhere at a defined plugin-location on the hard disk.
Before calling the script, the C++ class wants to expose some of its methods to the script for callbacks (the script should only be able to call this methods this time, i.e. when the script has finished execution and gets invoked from another place in the c++ app, it should not be able to call the class methods anymore. Also, I don't want to expose the whole class to the script - only the specific methods and the script should not be able to create instances of the class. Furthermore, I don't want that other python scripts are able to call the exposed methods, only the one that I'm going to call.)
After "registering" the class methods to the script, the c++ app calls the needed function in the script and gets the return value as a c++ type (e.g. a std::list)
I think the third point is the tricky part here and I've no idea how I can achieve this...
Is this possible?
Absolutely, yes.
How can I do that?
In the most general sense,
Import python libraries with:
boost::python::object obj = boost::python::import("module_name");
Access library objects and subobjects and functions with:
obj.attr("name");
That should be enough to get you going - as you get further, the details are in the documentation.
(Example:)
auto calendar = boost::python::import( "calendar" );
auto leap = calendar.attr("isleap")("2015");

plugin pattern with .dll. how can I extract plugin interface from dll?

I have an application that's suppose to be realized in plugin pattern.
Plugins are located in dll files and I'm loading them on the fly, depending on the parameter given from a user via command line. That is, if user wants to use plugin1 he types that name as a parameter in command line when running the app and I am supposed to load it on the fly.
Since I'm using plugin pattern I have an interface (since working in c++ it's an abstract class), that all of the plugins classes implement.
My dilemma is where to put the interface class? In order to have dlls built I will have to have a declaration of interface in every dll.
I want to avoid the need for changing the interface in all of dlls when there is a need for change in interface.
On the other hand if I declare interface class in main app my dlls wont be compiled and built?
Do you have a suggestion on how to extract the interface class from dlls and put it in the main app, so when I want to change it's code, wouldn't need to change it in a dozen of places (that is, in every dll).
Thanks in advance,
Cheers
You will have to store the interface definition in a common location (separate .h file in say \inc subdirectory) and you will have to recompile all the libraries once you change the interface. There's no way around that in C++. If you need the ability to uniquely indentify interfaces you can use something like COM and change interface id each time you break the interface (again you will have to recompile the implementations, but with COM the client will not run into undefined behavior because of DLL hell).
If by "interface" you are talking about the header file that describes your base-abstract class, I see no real issue.
You can share and use a file (here, a "header file") among several projects (a "project" is either your main application or one of your plugins). In your case, it actually makes perfect sense.
Every DLL needs to have the same exported function that returns a pointer to your interface. Each DLL should be responsible for instantiating the 'interface' (Really subclass actually).
So the main app will come along, call LoadLibrary on the DLL, and then using GetProcAddress, will call the exported function on the DLL. The exported function should then instantiate the concrete interface and return a pointer to it.
Question:
"Where to put the interface"
Answer:
In your 'public' API folder.
I once did this in C#, but maybe it can help you. I created an interface and abstract class in a separate project, which the main app and the plugins reference to. That way there is only one place for edits if necessary.
Main App.exe <-> PluginInterface.dll <-> APlugin.dll
Not sure how you would accomplish this in C++, I guess you could create a separate dll for the plugin interface and load it from your exe and your plugin dll's.
Hope that helps.

how to use dll?

i have have a program/project in vs2008 that uses a third party static lib. Now, it has come to my attention that i need to offer some api's via a dll. Apparently a thrid party program will use my dll via the apis i will provide.
Can anyone give me some direction as to what I need to do? would i need to just create a dll in vs2008 and just copy and paste my method logic in the apis that i provide?
are there any potential issues i need to worry about?
thank you
I suggest you check out this MSDN tutorial on creating & using DLLs.
There are unfortunately many potential issues to think about. A very brief and by no means complete list of the ones that pop in to my head:
You need to be aware of potential errors passing CRT objects across DLL boundaries
If you allocate objects in one module and deallocate them in the other, your DLL and the client code must link to the same CRT
It is very important that you keep the interface seperate from the implementation in your DLLs header files. This means you often can't do thing like use std::string as function parameters, or even as private member variables.
If I think of more or find more links, I'll add them.

Should I put global application details in a static class?

I'm currently maintaining a legacy C++ application which has put all the global application details in a static class, some of the variables stored are:
application name
registry path
version number
company name etc..
What is the recommended method for storing and accessing system application details?
If it never changes then why not. However, if not I'd externalise it into data that's loaded at run time. This way it can change without rebuild.
And since you include version number, I'd suspect the latter is way to go.
From my C++ days I recall builds taking not inconsequential times.
I'd rather use a namespace if no instances of the class will be created.
no hurt, and I think to use a singleton is even better.