Is it possible to do method swizzling in android using java? i would like to intercept a system method and log its parameters then process it normally
I think that technique could not be used using Java in any environment.
Maybe you could achieve a similar result using AOP.
But what you can do with that looks limited on Android. See Aspect-oriented programming in android. In fact, since you won't be compiling the target code (system method), compile-time weaving (which appears to be all you could use on Android) will be useless for this case. As is this answer I suppose.
One other thought... I guess you want to do this logging consistently. But if you needed this to debug a problem, you could do it using a conditional breakpoint in Eclipse.
A conditional expression can contain arbitrary Java code and may
contain more than one statement, allowing breakpoint conditions to
implement features like tracing. For example, a condition can execute
a print statement and then return a hard coded value to never suspend
("System.out.println(...); return false;").
I don't know specifically whether this works with methods in the Android SDK. But it does work with methods in the Java SDK. For example, here is simple code:
System.err.println("foo");
I made a conditional breakpoint in PrintStream.print, like this:
System.err.println("hello: " + arg0);
return false;
And the console output when debugging in the program is this:
hello: foo
foo
Note that since the JDK is not compiled with debug symbols, I can't refer to method parameters by name, but using the arg0..argn.
Related
I'm currently debugging some code that looks like this:
if (!clazz.isAssignableFrom(TypeName.class)){
return
}
Using the standard Eclipse debugging tools, I can inspect both classes and see that their names are both
com.packagename.package1.TypeName
I'd like to step into the isAssignableFrom() method that is being used to fail this evaluation when it seems like it should be passing to narrow down what the issue is. I've followed the answers from this question however, when attempting to "Step Into" isAssignableFrom(), Eclipse skips the line and goes right to the return statement, providing me no information about why two of the exact same type somehow aren't assignable from or to one another.
How can I step into this method to see which comparison is failing in an effort to fix the obvious issue with my TypeName class?
You cannot. It's a native method. There is no Java implementation to step into; it's baked into the JVM.
Likely the classes are loaded from different classloaders.
You could check with cls.getClassLoader().hashCode()
I'm writing a program in Java. I find that reading and debugging code is easiest when the paradigm techniques are consistent, allowing me very quickly assume where and what a problem is.
Doing this has, as you might guess, made my programming much faster, and so I want to find a way to enforce these rules.
For example, lets say I have a method that makes changes to the state of an object, and returns a value. If the method is called outside of the class, I don't ever want to see it resolve inside parameter parentheses, like this:
somefunction(param1, param2, object.change_and_return());
Instead, I want it to be done like this:
int relevant_variable_name = object.change_and_return();
somefunction(param1, param2, relevant_variable_name);
Another example, is I want to create a base class that includes certain print methods, and I want all classes that are user defined to be derived from that base class, much in the way java has done so.
Within my objects, is there a way I can force myself (and anyone else) to adhere to these rules? Ie. if you try to run code that breaks the rules, it will terminate and return the custom error report. Also, if you write code that breaks the rules, the IDE (I use eclipse) will recognize it as an error, underline and call the appropriate javadoc?
For the check and underline violations part:
You can use PMD, it is a static code analyzer.
It has a default ruleset, and you can write custom rules matching what you need.
However your controls seem to be quite complex to express in "PMD language".
PMD is available in Eclipse Marketplace.
For the crash if not conform part
There see no easy way to do it.
Hard/complex ways could be:
Write a rule within PMD, run the analysis at compile time, parse the report (still at compile time) and return an error if your rule is violated.
Write a Java Agent doing the rule check and make it crash the VM if the rule is violated (not sure it is really feasable, agents are meant for instrumentation).
Use reflection anywhere in your code to load classes, and analyze loaded class against your rules and crash the VM if the rule is violated (seriously don't do this: the code would be ugly and the rule easily bypassable).
I am trying to get the caller class and method name inside a function in a Scala app. I am currently making use of the stack trace, but the performance has decreased. I am doing something like
stackTrace(CodeDepth).getClassName
stackTrace(CodeDepth).getMethodName
I have found the Java reflection to be a lot more faster, but i can only get the class name with
sun.reflect.Reflection.getCallerClass(CodeDepth).getName()
Is there a way to get the method name (and optionally the line number) via reflection? Maybe using Scala's reflection?
Thanks
Unfortunately, there is no non-expensive method to do this. There is a Java Enhancement Proposal to add a better alternative, but this doesn't help unless you can wait until Java 9 (and it isn't guaranteed to be included anyway).
On the other hand, is this really a hotspot in your code? This should only matter if it's called in a loop, and in this case you probably can call it once and cache the result.
For Scala you can just use the sourcecode library from https://github.com/lihaoyi/sourcecode and just do something like:
def log(foo: String)(implicit line: sourcecode.Line, file: sourcecode.File) = {
println(s"${file.value}:${line.value} $foo")
}
log("Foooooo") // sourcecode/shared/src/test/scala/sourcecode/Tests.scala:86 Fooooo
Lets assume following Java class:
class MyClass {
public String methodA( String data, String expression ) {
// expression is evaluated using data
// ...
// this leads to a result which is returned
return result;
}
}
Note, that expression is an instance of an expression language (DSL). Thus, the evaluation of expression using data depends on the combination of both. Normally, expression is a fixed value which does not change often and data can change throughout all invocations.
Well, sometime later a bug is found in MyClass.methodA(String,String). The bug resides in some underlying class and only occurs for some special combination of expression and data. A JUnit test is easily written for this special case and can be fixed.
Unfortunately, this method is used frequently across the whole project. Eclipse call hierarchy identifies more than 97 other methods where this method is used. I now fear regression, if I just apply the bugfix. To feel more safe, I would like to do some regression testing.
Normally, unit tests should consider all important types of invocations, especially border cases. But, as expression is a DSL which can vary highly, it's not easy to test-cover all potential usage. Additionally, those tests would not identify false usage relying on the bug.
So my idea is to proceed in the following way:
Find all invocations of this method (like using "Call hierarchy" in Eclipse) and extract all the values for expression.
Sample enough real-life values for data (e.g. from database) and cross-evaluate all expressions from the first step on it using the original version of MyClass.methodA(String,String). Save the triples (data, expression, result) to a file.
Implement bugfix.
Test method MyClass.methodA(String,String) using the above file to assert that the results have not changed.
Following questions:
What do you think of this approach?
Using call hierarchy in Eclipse I can only copy and paste the calling methods but not the exact invocation including arguments to clipboard (cf. step 1). I would have to copy the invoking call by hand for each method found. How do I extract the invocations in a convenient way (in the complete Eclipse workspace, thus in several projects)?
IMHO I am only testing one single method, thus the tests covers only one unit. Is it ok to use JUnit for step 4 or is there something more sophisticated?
As the expected additional value by Testing your software is to cover the most circumstances with lowest costs and maximum outcome, I would agree with your approach.
Collecting reallife samplevalues from your software and save them to a representative file should not be that complex to realize and seems to me as the best way to analyze this thing. Even if you have to copy it manually.
Is it possible to see the return value of a method after the line has been run and before the instruction pointer returns to the calling function?
I am debugging code I can't modify (read: don't want to re-compile a third party library), and sometimes it jumps to code I don't have source to or the return expression has side effects that stop me being able to just run the expression in the Display tab.
Often the return value is used in a compound statement, and so the Variables view will never show me the value (hence wanting to see the result before control returns to the calling function).
UPDATE: I can't use the expression viewer as there are side-effects in the statement.
This feature was added to Eclipse version 4.7 M2 under Eclipse bug 40912.
To use it:
step over the return statement (using "Step Over" or "Step Return")
now the first line in the variable view will show the result of the return statement, as "[statement xxx] returned: "
See Eclipse Project Oxygen (4.7) M2 - New and Noteworthy for details.
Found a really good shortcut for this.
Select the expression which returns the value and press
Ctrl + Shift + D
This will display the value of the return statement. This is really helpful in cases where you can't or don't want to change just for debugging purpose.
Hope this helps.
Note: Have not tested this with third party libraries, but it is working fine for my code.
Tested this on Eclipse Java EE IDE for Web Developers. Version: Juno Service Release 1
That's why I always stick with the following pattern for methods:
MyReturnedType foo() {
MyReturnedType result = null;
// do your stuff, modify the result or not
return result;
}
My rules:
Only one return statement, only at the end of the method (finally allowed after it)
Always have a local called result which holds the returned value, starting from a default.
Naturally, the most trivial getters are exempt.
This is actually a long standing bug in Eclipse, dating back from the very first days of the IDE: https://bugs.eclipse.org/bugs/show_bug.cgi?id=40912
I am curious about to learn the answer to this question also.
In the past, when dealing with 3rd party library like that, what I did is to create a wrapper class or child class that delegate to the parent class and do my debugging in the wrapper/child class. It takes extra work though.
"Now when you return from a method, in the upper method, in the variable view it shows the return value of the previously finished call" [1]
[1] https://coffeeorientedprogramming.wordpress.com/2016/09/23/eclipse-see-return-value-during-debugging/
Tough one. My experience, outside of Eclipse, is that if you might need to see the return value, it is best to assign it to a local variable in the function so that the return statement is a simple return varname; and not return(some * expression || other);. However, that's not dreadfully helpful to you since you say you can't (or don't want to) modify or even recompile the code. So, I don't have a good answer for you - perhaps you need to reconsider your requirement.
Depending on the return statement, you can highlight the expression that is being returned and from the right-click menu, there should be something like "evaluate expression" (I don't have eclipse in front of me now, but it's something like that). It will show you what is going to be returned.
This is a bit far-fetched, but as there doesn't seem to be a simple way:
You could use AspectJ to instrument the JAR with aspects that get hold of the return value of the methods you're interested in. According to Eclipse's documentation, AspectJ programs can be debugged like other programs.
There are two options to weave your classes without recompiling the library :
Post-compile weaving if processing the binary JAR is acceptable;
Load-time weaving, which requires activating a weaving agent in the VM.
See the eclipse documentation (link above) and also the AspectJ Development Environment Guide.
For #Daniel Meyer answer's to work, ensure that 'Show method result after a step operation (if supported by the VM; may be slow)' is checked. The option is accessible via;
Windows> Preferences> Java> Debug> Show method result......