-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to inject POJO with generated classes #14
Comments
Jadex uses kernels to extends the platform with different kinds of components that can each bring their completely own definitions and execution engines. One component of a kernel is the component factory that has the purpose to create a running component for some model (or file) name. Besides that it is also possible to start pojo agents directly. We have an example for that in jadex.micro.testcases.pojostart. It just creates an agent pojo and calls addComponent to start it: PojoStartAgent pojo = new PojoStartAgent(); Is that sufficient for your use case? |
The PojoStartAgent approach is still dependent on a From what I can see, all of the existing machinery seems to depend on class files being able to be found: this is how Factories are matched by filter as well I believe: In my case, I have a dynamically constructed class (and pojo is an instance of that class), calling
Since I have an actual instance of the class, I don’t see why reading any Is there a chance that injecting pojo’s without Jadex having access to the corresponding |
The factory uses the pojo class to read the model, i.e. beliefs, plans and goals. I think that this use case could be supported by trying to fallback to pojo class when class could not be found otherwise. Could you provide us with a minimal example in which that error occurs so that we can test/try out with it? |
Given the following package r;
import jadex.bdiv3.runtime.BDIAgent;
public class Hello extends BDIAgent {} We now compile this file using package some.package;
import java.util.HashMap;
//Define Custom ClassLoader
public class Loader extends ClassLoader {
private HashMap<String, byte[]> byteDataMap = new HashMap<>();
public Loader(ClassLoader parent) {
super(parent);
}
public void loadDataInBytes(byte[] byteData, String resourcesName) {
byteDataMap.put(resourcesName, byteData);
}
@Override
protected Class<?> findClass(String className) throws ClassNotFoundException {
if (byteDataMap.isEmpty())
throw new ClassNotFoundException("byte data is empty");
String filePath = className.replaceAll("\\.", "/").concat(".class");
byte[] extractedBytes = byteDataMap.get(filePath);
if (extractedBytes == null)
throw new ClassNotFoundException("Cannot find " + filePath + " in bytes");
return defineClass(className, extractedBytes, 0, extractedBytes.length);
}
public static Object getHelloInstance() throws IOException {
//prepare the bytes array
byte[] byteData = …; // Use the bytes from Hello.bytes file, loaded into an array of bytes
Loader loader = new Loader(this.getClass().getClassLoader());
//Load bytes into hashmap
loader.loadDataInBytes(byteData, "r/Hello.class");
Class<?> rHello = loader.loadClass("r.Hello");
Object o = rHello.newInstance();
return o;
// Now start a jadex platform, and call platform.addComponent(o) to see my error
}
}
NB, it is important to remember that at no point do you ever actually have access to the bytes of the class in my actual use case, as my classes are dynamically created in memory; the important thing to remember is that you can call |
Started looking into that issue. It is not trivial to support but hopefully there is some workaround for that case. I will report my findings |
Good news. I have implemented a solution, so that agents can be created directly from pojo without the requirement of having the class on persistent storage. This required some internal API changes and of course only works for kernels with pojo support like BDI based on Java and micro agents. You can see how it works by looking at the new testcase in jadex.bdiv3.testcases.pojowithoutclass.Main (partially based on your code). Currently we need to fix another small issue to make our build get through but that should not take too long. |
I’m trying to define agents in an interactive environment;
Using the recently released
jadex.bdiv3.runtime.BDIAgent
I can easily define my agents without a separate bytecode enhancement step, but I still need to have a ComponentFactory for the generated class;Problem is that component factories seem to assume/require an on-disk
.class
file, which naturally does not exist for classes that only exist in-memory of the JVM process.Provided I stick to POJO’s that I manually construct, Is there a trick or short-circuit I can use to not need a ComponentFactory? Alternatively, is there a way for ComponentFactory to support classes that only exist in-process? Obviously this is about explorative programming, so there is no need to support with distributed/networked/multi-process JVM situations.
For some context, the problematic stack trace I get on trying to load my in-process defined agent POJO, a subclass of BDIAgent:
NB, everything works as expected if I have the same code, but pre-compile it to class files. I just would like the option to make changes in a running process (perhaps restarting the jadex platform) without having to also write class files to disk.
The text was updated successfully, but these errors were encountered: