I have C++ solution with some apps and static libraries:
UserRace1.exe
UserRace2.exe
GreenBody.lib
BlueBody.lib
RedBody.lib
BigWheels.lib
MiddleWheels.lib
SmallWheels.lib
V8Engine.lib
V12Engine.lib
RaceTires.lib
WinterTires.lib
SimpleTires.lib
Garage.lib
In application, I just simulate race, one application for each race. Libs consist classes that describe parts of the car (body, wheels, engine, etc.). Every class implement some interface (IBody, IWheels, IEngine, etc.), that described in Garage lib. And Garage.lib should create cars, using parts.
So, I pass car parameters to application, as example: -Car1 -RedBody -MiddleWheels -V8Engine -RaceTires -Car2 -BlueBody -SmallWheels -V12Engine -WinterTires . Application call Garage class: Garage::GetCar(string body, string wheels, string engine, string tires) and garage return Car object, that we use in app. Pay attention, that I pass this arguments like a string. It's important.
Now, about what I want. I write only Garage lib. Other libs will be write by other people. And I want my library has been universal. At this moment, when new part added (e.g. BlackBody.lib) I must add support of this in my Garage.lib. something like:
...
else if (body == "RedBody")
{
car->body = new RedBody();
}
else if (body == "BlackBody")
{
car->body = new BlackBody();
}
...
But I want to get this types dynamicaly. Like:
foreach (Librarian lib in Application.GetLibs())
{
foreach (Type type in lib)
{
if (type is IBody)
{
if (((IBody)type)::GetColor() == color)
{
car->body = type.GetInstance();
return;
}
}
}
}
Then, if someone add new type, I will not change my library. Problem is, that I write on C++, not C#. And I don't know how to implement it.
Maybe I should use dll instead of static lib? Is this an only way? And if so, whether there would be problems that the applications and dlls use one library (Garage.lib)? Cause they use different runtime libraries (/MT and /MD).
You could have an entirely "dynamic" solution, using DLLs, provided that:
you could derive a Dll name ("BlackBody.dll") from a string '"BlackBody")
each Dll exports a factory function, with a predictable name ("Factory", or "BlackBodyFactory")
You dynamically load the Dlls, and get the factory pointer function via GetProcAddress
your Garage.lib code only knows about the Body base class, because that's what a "body" factory function will return
You should avoid mixing different CRT in the same process. Mixing is possible but involves extra care/work.
Related
Aside from recompiling rt.jar is there any way I can replace the currentTimeMillis() call with one of my own?
1# The right way to do it is use a Clock object and abstract time.
I know it but we'll be running code developed by an endless number of developers that have not implemented Clock or have made an implementation of their own.
2# Use a mock tool like JMockit to mock that class.
Even though that only works with Hotspot disabled -Xint and we have success using the code bellow it does not "persist" on external libraries. Meaning that you'd have to Mock it everywhere which, as the code is out of our control, is not feasible. All code under main() does return 0 milis (as from the example) but a new DateTime() will return the actual system millis.
#MockClass(realClass = System.class)
public class SystemMock extends MockUp<System> {
// returns 1970-01-01
#Mock public static long currentTimeMillis() { return 0; }
}
3# Re-declare System on start up by using -Xbootclasspath/p (edited)
While possible, and though you can create/alter methods, the one in question is declared as public static native long currentTimeMillis();. You cannot change it's declaration without digging into Sun's proprietary and native code which would make this an exercise of reverse engineering and hardly a stable approach.
All recent SUN JVM crash with the following error:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736
4# Use a custom ClassLoader (new test as suggested on the comments)
While trivial to replace the system CL using -Djava.system.class.loader JVM actually loads up the custom classLoader resorting to the default classLoader and System is not even pushed trough the custom CL.
public class SimpleClassLoader extends ClassLoader {
public SimpleClassLoader(ClassLoader classLoader) {
super(classLoader);
}
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
}
We can see that java.lang.System is loaded from rt.jar using java -verbose:class
Line 15: [Loaded java.lang.System from C:\jdk1.7.0_25\jre\lib\rt.jar]
I'm running out of options.
Is there some approach I'm missing?
You could use an AspectJ compiler/weaver to compile/weave the problematic user code, replacing the calls to java.lang.System.currentTimeMillis() with your own code. The following aspect will just do that:
public aspect CurrentTimeInMillisMethodCallChanger {
long around():
call(public static native long java.lang.System.currentTimeMillis())
&& within(user.code.base.pckg.*) {
return 0; //provide your own implementation returning a long
}
}
I'm not 100% sure if I oversee something here, but you can create your own System class like this:
public static class System {
static PrintStream err = System.err;
static InputStream in = System.in;
static PrintStream out = System.out;
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
System.arraycopy(src, srcPos, dest, destPos, length);
}
// ... and so on with all methods (currently 26) except `currentTimeMillis()`
static long currentTimeMillis() {
return 4711L; // Your application specific clock value
}
}
than import your own System class in every java file. Reorganize imports in Eclipse should do the trick.
And than all java files should use your applicatikon specific System class.
As I said, not a nice solution because you will need to maintain your System class whenever Java changes the original one. Also you must make sure, that always your class is used.
As discussed in the comments, it is possible that option #3 in the original question has actually worked, successfully replacing the default System class.
If that is true, then application code which calls currentTimeMillis() will be calling the replacement, as expected.
Perhaps unexpectedly, core classes like java.util.Timer would also get the replacement!
If all of the above are true, then the root cause of the crash could be the successful replacement of the System class.
To test, you could instead replace System with a copy that is functionally identical to the original to see if the crashes disappear.
Unfortunately, if this answer turns out to be correct, it would seem that we have a new question. :) It might go like this:
"How do you provide an altered System.currentTimeMillis() to application classes, but leave the default implementation in place for core classes?"
i've tried using javassist to remove the native currentTimeMills, add a pure java one and load it using bootclasspath/p, but i got the same exception access violation as you did. i believe that's probably because of the native method registerNatives that's called in the static block but it's really too much to disassemble the native library.
so, instead of changing the System.currentTimeMills, how about changing the user code? if the user code already compiled (you don't have source code), we can use tools like findbugs to identify the use of currentTimeMillis and reject the code (maybe we can even replace the call to currentTimeMills with your own implementation).
I was searching through stackoverflow questions but none of them answered my question. I have a game engine and I want to load player AI (written in c++) in runtime.
Click on button, file dialog appears
Choose file with AI (.dll or something?)
Click on 'start' button, game starts using AI's that I add.
AI could be a method or whole class, it doesn't matter. I think I should generate .dll but I not sure how to do that. This class should look like this:
class PlayerAI
{
void computeSomething(list of argument, Object& output)
{
// some logic
}
}
Assuming pure Windows platform since none specified -
If you want to inject DLL, first obtain a handle to it using LoadLibrary-function like so:
HINSTANCE handleLib;
handleLib = LoadLibrary(TEXT("YourDLL.dll"));
You may then obtain a function pointer to a specific function in the lib. Like this:
FUNC_PTR func;
func = (FUNC_PTR) GetProcAddress(handleLib, "yourFunc");
Then you can call the function like so:
(func) (L"TESTSTRING HERE");
When done, call FreeLibrary(libhandle)
How to declare a function as exported is in VS for instance like this (this is needed to mark your function in your DLL that you precompile:
__declspec(dllexport) int __cdecl yourFunc(LPWSTR someString)
{
//Code here...
}
Since you mention already compiled DLLs, you want to look at LoadLibrary and GetProcAddress. That's how you do runtime loads of DLLs and extract specific functions from them.
Examples can be found under Using Run-Time Dynamic Linking.
Hi have 6 projects defined in my IDE.
EventHelper
ConfigParser
OfficeEventHandler
Messaging
LoggingAndPersistence
ScreenCamera
EventHelper has the entry point. The rest of the projects are the DLL which gets absorbed by the EventHelper.
Messaging and ConfigParser is being used in every other DLLs as well. So the code for loading the DLLs and acessing it is common in all the modules (Code Redundancy).
dllHandle_parser = ::LoadLibrary(TEXT("ConfigParser.dll"));
if (!dllHandle_parser){
return;
}
configParserClient_fctry = reinterpret_cast<configParser>(::GetProcAddress(dllHandle_parser, "getParserInstance"));
if (!configParserClient_fctry) {
::FreeLibrary(dllHandle_parser);
return;
}
parser = configParserClient_fctry();
And the similar code for Messaging
My question is
Is there a way where I can have one DLL called ObjectFactory where I can give the name of the class (in runtime, in string format) whose to be created. Something like
ObjectFactory.getInstance("ConfigParser/Messaging"). (Java like Class.forName("className"))
Or if not possible this way, what would be the suggested architecture?
I am working on a system that uses drools to evaluate certain objects. However, these objects can be of classes that are loaded at runtime using jodd. I am able to load a file fine using the following function:
public static void loadClassFile(File file) {
try {
// use Jodd ClassLoaderUtil to load class into the current ClassLoader
ClassLoaderUtil.defineClass(getBytesFromFile(file));
} catch (IOException e) {
exceptionLog(LOG_ERROR, getInstance(), e);
}
}
Now lets say I have created a class called Tire and loaded it using the function above. Is there a way I can use the Tire class in my rule file:
rule "Tire Operational"
when
$t: Tire(pressure == 30)
then
end
Right now if i try to add this rule i get an error saying unable to resolve ObjectType Tire. My assumption would be that I would somehow need to import Tire in the rule, but I'm not really sure how to do that.
Haven't use Drools since version 3, but will try to help anyway. When you load class this way (dynamically, in the run-time, no matter if you use e.g. Class.forName() or Jodd), loaded class name is simply not available to be explicitly used in the code. I believe we can simplify your problem with the following sudo-code, where you first load a class and then try to use its name:
defineClass('Tire.class');
Tire tire = new Tire();
This obviously doesn't work since Tire type is not available at compile time: compiler does not know what type you gonna load during the execution.
What would work is to have Tire implementing some interface (e.g. VehiclePart). So then you could use the following sudo-code:
Class tireClass = defineClass('Tire.class');
VehiclePart tire = tireClass.newInstance();
System.out.println(tire.getPartName()); // prints 'tire' for example
Then maybe you can build your Drools rules over the interface VehiclePart and getPartName() property.
Addendum
Above make sense only when interface covers all the properties of dynamically loaded class. In most cases, this is not a valid solution: dynamically loaded classes simply do not share properties. So, here is another approach.
Instead of using explicit class loading, this problem can be solved by 'extending' the classloader class path. Be warn, this is a hack!
In Jodd, there is method: ClassLoaderUtil.addFileToClassPath() that can add a file or a path to the classloader in the runtime. So here are the steps that worked for me:
1) Put all dynamically created classes into some root folder, with the respect of their packages. For example, lets say we want to use a jodd.samples.TestBean class, that has two properties: number (int) and a value (string). We then need to put it this class into the root/jodd/samples folder.
2) After building all dynamic classes, extend the classloaders path:
ClassLoaderUtil.addFileToClassPath("root", ClassLoader.getSystemClassLoader());
3) load class and create it before creating KnowledgeBuilder:
Class testBeanClass = Class.forName("jodd.samples.TestBean");
Object testBean = testBeanClass.newInstance();
4) At this point you can use BeanUtils (from Jodd, for example:) to manipulate properties of the testBean instance
5) Create Drools stuff and add insert testBean into session:
knowledgeSession.insert(testBean);
6) Use it in rule file:
import jodd.samples.TestBean;
rule "xxx"
when
$t: TestBean(number == 173)
then
System.out.println("!!!");
end
This worked for me. Note that on step #2 you can try using different classloader, but you might need it to pass it to the KnowledgeBuilderFactory via KnowledgeBuilderConfiguration (i.e. PackageBuilderConfiguration).
Another solution
Another solution is to simply copy all object properties to a map, and deal with the map in the rules files. So you can use something like this at step #4:
Map map = new HashMap();
BeanTool.copy(testBean, map);
and later (step #5) add a map to Drools context instead of the bean instance. In this case it would be even better to use defineClass() method to explicitly define each class.
I am currently writing an application that will serve a similar purpose for multiple clients, but requires adaptations to how it will handle the data it is feed. In essence it will serve the same purpose, but hand out data totally differently.
So I decided to prodeed like this:
-Make common engine library that will hold the common functionalities of all ways and present the default interface ensuring that the different engines will respond the same way.
-Write a specific engine for each way of functioning....each one compiles into its own .dll.
So my project will end up with a bunch of libraries with some looking like this:
project_engine_base.dll
project_engine_way1.dll
project_engine_way2.dll
Now in the configuration file that we use for the user preferences there will an engine section so that we may decide which engine to use:
[ENGINE]
Way1
So somewhere in the code we will want to do:
If (this->M_ENGINE == "Way1")
//load dll for way1
Else If (this->M_ENGINE == "Way2")
//load dll for way2
Else
//no engines selected...tell user to modify settings and restart application
The question is...How will I import my dll(s) this way? Is it even possible? If not can I get some suggestions on how to achieve a similar way of functioning?
I am aware I could just import all of the dlls right at the start and just choose which engine to use, but the idea was that I didn't want to import too many engines for nothing and waste resources and we didn't want to have to ship all of those dlls to our customers. One customer will use one engine another will use a different one. Some of our customer will use more than one possibly hence the reason why I wanted to externalize this and allow our users to use a configuration file for engine switching.
Any ideas?
EDIT:
Just realized that even though each of my engine would present the same interface if they are loaded dynamically at runtime and not all referenced in the project, my project would not compile. So I don't have a choice but to include them all in my project don't I?
That also means they all have to be shipped to my customers. The settings in the configuration would only dictate with class I would use to initialize my engine member.
OR
I could have each of these engines be compiled to the same name. Only import one dll in my main project and that particular engine would be used all the time. That would render my customers unable to use our application for multiple clients of their own. Unless they were willing to manually switch dlls. Yuck
Any suggestions?
EDIT #2:
At this point seeing my options, I could also juste make one big dll containing the base engine as well as all the child ones and my configuration to let the user chose. Instead of referencing multiple dlls and shipping them all. Just have one huge one and ship/reference that one only. I am not too fond of this either as it means shipping one big dll to all of my customers instead of just one or two small ones that suit there needs. This is still the best solution that I've come up with though.
I am still looking for better suggestions or answers to my original question.
Thanks.
Use separate DLLs for each engine and use LoadLibrary in your main project to load the specific engine based on the configuration.
Have your engine interface in some common header file that all engines will derive from and this interface will be used in your main project aswell.
It might look like this:
// this should be an abstract class
class engine {
public:
virtual void func1() = 0;
virtual void func2() = 0;
...
};
In each different engine implementation export a function from the DLL, something like this:
// might aswell use auto_ptr here
engine* getEngine() { return new EngineImplementationNumberOne(); }
Now in your main project simply load the DLL you're interested in using LoadLibrary and then GetProcAddress the getEngine function.
string dllname;
if (this->M_ENGINE == "Way1")
dllname = "dllname1.dll";
else if (this->M_ENGINE == "Way2")
dllname = "dllname2.dll";
else
throw configuration_error();
HMODULE h = LoadLibraryA(dllname.c_str());
typedef engine* (*TCreateEngine)();
TCreateEngine func = (TCreateEngine)GetProcAddress(h, "getEngine");
engine* e = func();
The name of the exported function will probably get mangled, so you could either use DEF files or extern "C" in your DLLs, also don't forget to check for errors.
The solution I came to is the following:
Engine_Base^ engine_for_app;
Assembly^ SampleAssembly;
Type^ engineType;
if (this->M_ENGINE == "A")
{
SampleAssembly = Assembly::LoadFrom("path\\Engine_A.dll");
engineType = SampleAssembly->GetType("Engine_A");
engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2));
}
else
{
SampleAssembly = Assembly::LoadFrom("path\\Engine_B.dll");
engineType = SampleAssembly->GetType("Engine_B");
engine_for_app = static_cast<Engine_Base^>(Activator::CreateInstance(engineType, param1, param2, param3, param4));
}
I used the answer from Daniel and the comments that were made on his answer. After some extra research I came across the LoadFrom method.