How does CtMethod affects classloading? CtMethod.insertBefore() is ineffective - reflection

Please read along. I have a Lion class that has a method stayLion.
public class Lion {
//class Variables and methods
public void stayLion(String temp,int temp2,double temp3, boolean temp4,Food food) throws InterruptedException {
//method Body
}
}
The method takes in a Food instance as one of its parameter. Food class has cook method
public class Food{
public void cook(){
}
}
I am trying to instrument both these methods, stayLion and cook. The transform method is called for every class that is loaded by JVM.(Interesed to know, where and who calls it. Correct me if I am wrong) If classname matches with my desired list of classnames, I extract the list of methods, and verify the methodName and its parameter, I find the CtMethod instance for the method I wish to instrument (stayLion and cook).
public byte[] transform(ClassLoader loader, final String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
//verifying className(fully qualified), if same then,
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.getCtClass(className.replace("/","."));
CtMethod[] methods = ctClass.getDeclaredMethods();
for (CtMethod method : methods) {
//verifying method (name and parameter)
method.insertBefore( //some code );
}
}
However, in the process of verifying parameters for stayLion, the Food class gets loaded and transform method is not called, (I don't know the reason for this. The class loader is same. Why is transform method not called for Food class as it gets loaded?). To overcome this, I explicitly call transform method for Food class (in general, I call transform method everytime a class whose method I wish to instrument is in the parameter list of any other method I also wish to instrument).
transform(loader,"com/here/debugHelper/Food",null,protectionDomain,null);
But this explicit calling of transform method is ineffective. To be precise,
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.getCtClass(className.replace("/","."));
CtMethod[] methods = ctClass.getDeclaredMethods();
Till here, methods contains list of all methods of Food class. After verifying cook method with no parameter
for (CtMethod method : methods) {
//verifying method (name and parameter)
method.insertBefore( //some code );
}
But at this point, method.insertBefore() is ineffective and is not adding any code to the desired method.

The transform method is invoked by the JVM during class loading or redefinition. It does not make much sense for you to call the method directly unless you are testing.
If you are loading a class during a code manipulation, no class being loaded will be transformed. This is to avoid circularities in your instrumentation where instrumenting Aloads B and instrumenting B loads A. If you attempt to load the instrumented class itself, this will result in a ClassCircularityError.
I assume that when you instrument Lion, you are loading Food when processing the parameters. By using Javassist, you normally avoid this as Javassist loads class files directly but I figure that you are referencing the Lion class as a constant somewhere and therefore load it somwhere in your transformer.

Related

ActivatorUtilities.CreateInstance giving "A suitable constructor not found" for simple examples

So I am building a complex case here with inheritance and IOC, need to use ActivatorUtilities to inject instances and pass parameters... no matter what I do I get the following error:
System.InvalidOperationException: 'A suitable constructor for type
'blabla.ISimpleTest' could not
be located. Ensure the type is concrete and all parameters of a public
constructor are either registered as services or passed as arguments.
Also ensure no extraneous arguments are provided.'
So in order to discard what could be the problem and ensure there is no constructor issues, I created a very very simple scenario that gives me the same error.
startup.cs
services.AddScoped<ISimpleTest, SimpleTest>();
the class and the interface, very simple here:
public interface ISimpleTest
{
}
public class SimpleTest : ISimpleTest
{
public SimpleTest()
{
}
}
test
var theInstance = ActivatorUtilities.CreateInstance<ISimpleTest>(ServiceProvider);
Additional notes
The ServiceProvider instance is fine (the rest/entire application depends on it).
Tried with and without adding the public constructor(empty params)
Tried also constructor with params, same error.
Tried to specify the params[] parameter, by sending null or empty array, same issue.
Extra test:
Just to confirm it's properly registered, I tried to get the instance using the Service provider, and works without issues:
//No issues this way:
var yyy = ServiceProvider.GetService<ISimpleTest>();
What am I doing here wrong? According to documentations, this should be enough to work

Run dynamic class based on field value

I have 3 classes each with a method which run some calculation and write the values in different fields, this method also writes the classname into a field from where the method runs from.
This works fine.
I recently created a button to re-run the method, from the class the method originally run from.
For example:
Class1 RunMethod
Class2 RunMethod
Class3 RunMethod
I am now creating the method for the action button when clicked, but I have no clue how to run a specific method from the class where it originally ran from. The class name is in a field.
I think I can accomplish this with SysDictClass, but I have no clue how to start, how can I best start with this method?
This should get you the idea. I wrote it in AX 2009 but it should probably work in AX 2012 as well.
public static client void SysDictClassJob()
{
ClassId classId;
Object obj;
SysDictClass sysDictClass;
;
// Create instance (if you are going to call a member method)
classId = className2Id('SomeClass');
obj = classFactory.createClass(classId);
// Invoke member method
sysDictClass = new SysDictClass(classId);
sysDictClass.callObject('yourMemberMethod', obj);
// Invoke static method
sysDictClass.callStatic('yourStaticMethod');
}

Reflection: No functions in LibraryMirror

I'm trying to build an entity manager in Dart which uses reflection. The idea is that the method getById(String id, String returnClass) calls a method _get[returnClass]ById(String id).
To accomplish this I'm using dart:mirrors and try to determine if my entity manager object has such a method and call it then. Unfortunately the LibraryMirror doesn't contain any functions.
class EntityMgr {
Object getById(String id, String returnClass) {
InstanceMirror result = null;
String methodName = '_get'+returnClass+'ById';
// Check if a method '_get[returnClass]Byid exists and call it with given ID
if(_existsFunction(methodName)) {
Symbol symbol = new Symbol(methodName);
List methodParameters = new List();
methodParameters.add(id);
result = currentMirrorSystem().isolate.rootLibrary.invoke(symbol, methodParameters);
}
return result;
}
Product _getProductById(String id) {
return new Product();
}
bool _existsFunction(String functionName) {
return currentMirrorSystem().isolate.rootLibrary.functions.containsKey(functionName);
}
}
The mirrors library has changed significantly since this response and no longer reflects the api mentioned in this answer
Isolate's are for concurrent programming and you probably don't have any isolates running. Where you want to look is currentMirrorSystem().libraries, or you can use currentMirrorSystem().findLibrary(new Symbol('library_name')).
You need to know the library because a function or class with the same Symbol could me in different libraries but have completely different signatures.
how to invoke class form dart library string or file shows how to get the class mirror from the library and class name.
The ClassMirror contains the methods, the getters and the setters. The methods mirror does not contain the getters or setters.
final Map<Symbol, MethodMirror> methods
final Map<Symbol, MethodMirror> getters
final Map<Symbol, MethodMirror> setters
That being said, you might want to check out the dart serialization at http://api.dartlang.org/docs/bleeding_edge/serialization.html since it might already do exactly what you're trying to do.

How can I get the name of the defined class in a parent static method in Groovy

Note: I found another answer that suggests that Java would redirect the static method call to it's own class even if it's called on a child class so I guess I need to find a Groovy work-around trick or it's just not going to be doable.
Here's the problem: I created an abstract generic "Launcher" class with a "public static void main". The idea is that you extend it and in your child class you annotate methods like this:
#Command("Show an explorere shell")
public dir() {
"explorer".execute()
}
The parent of this class has a main that goes through, reflects for the #Command annotation and if the method name matches your parameter, executes it.
The problem is that I can't figure out how to tell what the actual, instantiated class is within the parent's static main method.
I'm pretty sure there is a trick somewhere--"this" won't work in statics, stack traces don't contain the actual class, just the parent class, and I can't find any meta-info in the class or MetaClass objects that helps.
Currently I've gotten it to work by hard-coding the name of the child class into the parent's main like this:
public class QuickCli {
public static void main(String[] args} {
(new HardCodedChildClassName())."${args[0]}"()
}
}
I cut quite a bit out of that, but it's the general idea. I'd like to replace
"new HardCodedChildClassName()"
with something that will work for any class that extends this class.
Given the two code snips above, the command would be executed from the command line as:
groovy HardCodedChildClassName dir
Although I'd prefer not to make all the #Command methods static I could do so if I had to, but currently I'm not even convinced I could make that work.
I'm not sure that's possible. In any case, it's likely to be an ugly hack if it is. I'd suggest this alternative: Rather than using the static main() entry point, make QuickCli a Runnable. Groovy will automatically create an instance and call run() on it when it is launched.
One minor problem here is capturing the command-line arguments. Groovy handles this by passing them to a constructor with a String[] parameter. The instantiated class needs this constructor to capture the args, but in Java, constructors are not inherited. Fortunately, Groovy has an InheritConstructors annotation that works around this.
Here's an example of how this would look:
class QuickCli implements Runnable {
def args
QuickCli(String[] args) {
this.args = args
}
void run() {
"${args[0]}"()
}
}
#groovy.transform.InheritConstructors
class HardCodedChildClassName extends QuickCli {
#Command("Show an explorere shell")
public dir() {
"explorer".execute()
}
}

Singleton Class in Flex

I have a doubt,.... How would you create a Singleton class in Flex...
Is there any convention like the class name should eb Singleton or it should extend any other class.
How many Singleton class can a project have?
Can anyone say the real time usage of a Singleton class?
I am planning to keep my components label texts in a Singleton class... Is it a good approach.
Can of worms asking about singletons!
There are a few different options about creating singletons mainly due to AS3 not having private constructors. Here's the pattern we use.
package com.foo.bar {
public class Blah {
private static var instance : Blah;
public function Blah( enforcer : SingletonEnforcer ) {}
public static function getInstance() : Blah {
if (!instance) {
instance = new Blah( new SingletonEnforcer() );
}
return instance;
}
...
}
}
class SingletonEnforcer{}
Note that the SingletonEnforcer class is internal so can only be used by the Blah class (effectively). No-one can directly instantiate the class, they have to go through the getInstance() function.
hope I'm not hitting dead horses here :)
(edit: ahh, I'm just repeating phils link)
Gregors singleton implementation does not protect against invoking the constructor with a null value, as in:
var b:Blah = new Blah(null);
You will still have only 1 instance, but invoking the constructor is still possible with the consequences that follows.
If you absolutely must enforce the singleton, the constructor should make sure that the enforcer parameter isn't null.
public function Blah( enforcer : SingletonEnforcer ) {
if(!enforcer){
throw new Error("whoops!");
}
}
You should also be concerned about ApplicationDomain when loading swf files. External swf files that uses the same definitions, may have multiple singleton instances (1 in each separate applicationdomain) if you do not specify that the swf file must be loaded into the existing applicationdomain.
This means that Blah.getInstance() in AAA.swf is not the same instance as Blah.getinstance() in BBB.swf, if AAA.swf loads BBB.swf without a LoaderContext instance that tells the plugin to load BBB.swf into the same ApplicationDomain as AAA.swf
First you can reference a previous question to find out how to create a singleton class. You can find more info from a Yakov Fain presentation as well.
Second question, your project can technology have as may singleton class as you see fit but it will only create 1 instance of each. For example, in the cairngorm architecture you have 3 main singletons: controller, service and model. The number of actual class can very depending on your project.
Finally, A real world solutions would be. You have 2 components that need to talk to each other but you don't want them to know the other exists. Meaning sometimes the components are there and sometimes they are not...so you need them to be loosely coupled. you can uses singletons to pass the data from one component to the other with out "talking" to them directly.
Using singletons is a good approach if you need to pass data around your application from component to component and would like to decouple them from each other.
package com.foo.bar
{
public class MySingleton
{
private static var _instance:MySingleton = new MySingleton;
private var _myName:String;
public static function get instance():MySingleton
{
return _instance;
}
public function set myName(value:String):void
{
_myName = value;
}
public function get myName():String
{
return _myName;
}
}
}
Notice the absence of a constructor here.
Hello you could check out the following of a Flex Singleton Class example on http://www.how-to-code.com/flex/flex-design-patterns/flex-singleton-class.html

Resources