In my java code there is class A that has the following line:
Process localProcess = Runtime.getRuntime().exec(myString);
where myString is user supplied input and is passed to exec() at runtime.
Also there is a public method doSomething() in class A.
Can I somehow invoke doSomething() (through reflection, jdwp etc.) using exec() at runtime ?
Starting a new JVM just to call a single method? First, that would be really slow. And second, it would be highly unnecessary!
Reflection is what you want I guess. Here's some sample code.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
Class<Main> c = Main.class; // First get the class
try {
Method method = c.getMethod("doSomething"); // get the method by its name
method.invoke(new Main()); // call it on a new instance of Main
} catch (NoSuchMethodException e) {
System.out.println("Method is not found"); // print something when the method is not found
}
}
public void doSomething() {
System.out.println("I have done something!");
}
}
That would mean starting a whole new JVM just to make a method call.
If you are already "within" class A; what prevents you from calling doSomething() directly? Probably: only your lack of skills. If so, then work on your skills; and don't go for the next best solution you heard somebody mention how things might be done!
In essence: a self-claimed geek should always understand each and any concept he is using in his programs. If you want to use reflection, then study what reflection is about.
And please note: letting your users pass in arbitrary strings to have them executed, is a huge security NO GO. You should have mentioned in your question that you want to do this on purpose; and that you are fully aware of the potential consequences of doing so!
EDIT; given your latest comments.
In this case, a solution could be as simple as:
A) you write a new class, like
public class Invoker {
public static void main(String[] args) {
A.doSomething();
or if doSomething isn't static, you will need
A someA = new A( ... however you can create instances of A
A.doSomething()
B) Compile that, and then you can simply send a command like
java -cp WHATEVER Invoker
into your existing application. Of course, you have to work out the details; like providing a valid classpath to that call to java (that classpath has to include the location where Invoker.class lives; and of course A.class; and all of the dependencies that A has).
But keep in mind: doSomething() is executed in the scope of a different JVM. That means that most likely, it will not at all affect class A in that JVM where you trigger the call to exec!
Related
I would need help trying to understand why this is happening to me:
Using Java 1.8.0_131, I have a class such as this:
public class DynamicClassLoadingAppKO {
/*
* THIS VERSION DOES NOT WORK, A ClassNotFoundException IS THROWN BEFORE EVEN EXECUTING main()
*/
// If this method received ChildClassFromLibTwo, everything would work OK!
private static void showMessage(final ParentClassFromLibOne obj) {
System.out.println(obj.message());
}
public static void main(final String[] args) throws Throwable {
try {
final ChildClassFromLibTwo obj = new ChildClassFromLibTwo();
showMessage(obj);
} catch (final Throwable ignored) {
// ignored, we just wanted to use it if it was present
}
System.out.println("This should be displayed, but no :(");
}
}
Two other classes are being used up there: ParentClassFromLibOne and ChildClassFromLibTwo. The latter extends from the former.
There are two external libraries involved:
One library is called libone and contains the ParentClassFromLibOne class. The application includes this library in the classpath both for compiling and executing.
A second library is called libtwo and contains the ChildClassFromLibTwo class. The application includes this library in the classpath for compiling, but not for executing.
As far as I understand, the Java runtime should try to load the ChildClassFromLibTwo (which is not in the classpath at runtime) at this line:
final ChildClassFromLibTwo obj = new ChildClassFromLibTwo();
Given this class is not in the classpath, a ClassNotFoundException should be thrown, and given this line is inside a try...catch (Throwable), the System.out.println line at the end should be executed anyway.
However, what I get is the ClassNotFoundException thrown when the DynamicClassLoadingAppKO itself is loaded, apparently before the main() method is executed at all, and therefore not caught by the try...catch.
What seems more strange to me is that this behaviour disappears and everything works as I would expect if I change the signature of the showMessage() method so that instead of receiving an argument of the parent class, it is directly of the child class:
/*
* THIS VERSION WORKS OK, BECAUSE showMessage RECEIVES THE CHILD CLASS AS A PARAMETER
*/
private static void showMessage(final ChildClassFromLibTwo obj) {
System.out.println(obj.message());
}
How is this possible? What am I missing in the way class loading works?
For testing convenience, I have created a GitHub repository replicating this behaviour [1].
[1] https://github.com/danielfernandez/test-dynamic-class-loading/tree/20170504
OK, the details of why this happens are explained in this Spring Boot ticket [1] which I've been very lucky to be promptly pointed to by Andy Wilkinson. That was definitely a difficult one IMO.
Apparently, what happens in this case is that when the calling class itself is loaded, the verifier kicks in and sees that the showMessage() method receives an argument of type ParentClassFromLibOne. So far so good, and this would not provoke a ClassNotFoundException at this phase even if ParentClassFromLibOne was not in the classpath at runtime.
BUT apparently the verifier also scans method code and notes that there is a call in main() to that showMessage() method. A call that does not pass as an argument a ParentClassFromLibOne, but instead an object of a different class: ChildClassFromLibTwo.
So it is in this case that the verifier does try to load ChildClassFromLibTwo in order to be able to check if it really extends from ParentClassFromLibOne.
Interestingly this wouldn't happen if ParentClassFromLibOne was an interface, because interfaces are treated as Object for assignment.
Also, this does not happen if showMessage(...) directly asks for a ChildClassFromLibTwo as an argument because in such case the verifier does not need to load the child class to check it is compatible... with itself.
Daniel, I'm voting up your answer but I will not mark it as accepted because I consider it fails at explaining the real reason why this is happening at verify time (it's not the class in the signature of the method that's causing the ClassNotFoundException).
[1] https://github.com/spring-projects/spring-boot/issues/8181
This is a bit more complicated than you think. When a class is loaded, all functions are verified. During the verify phase also all referenced classes are loaded, because they are needed to calculated the exact types that are on the stack at any given location in the bytecode.
If you want that lazy behaviour, you have to pass the -noverify option to Java, which will delay the loading of classes until the functions that reference them are executed the first time. But don't use -noverify for security reasons when you don't have full control over the classes that will be loaded into the JVM.
I want to inject some code through annotations in java.
The plan is I have two methods beginAction() and endAction(). I want to annotate a method such that before executing the statements in the method the beginAction() will be put and after finishing executing them the endAction() will be put automatically. Is it possible. If yes please suggest me how to do.
#MyAnnotation
public void myMethod(){
// Statement 1;
// Statement 2;
}
At runtime the beginAction() and endAction() should be injected in the method through the annotation. That is it should become like the following at runtime.
public void myMethod{
beginAction();
// Statement 1;
// Statement 2;
endAction();
}
It looks like you need aspects. AspectJ is the most popular library in this case. You can read more about it here: https://eclipse.org/aspectj/docs.php
And here's the example of such aspect in use:
Class with intercepted method:
public class YourClass {
public void yourMethod() {
// Method's code
}
}
Aspect itself:
#Aspect
public class LoggingAspect {
#Around("execution(* your.package.YourClass.yourMethod(..))")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Do something before YourClass.yourMethod");
joinPoint.proceed(); //continue on the intercepted method
System.out.println("Do something after YourClass.yourMethod");
}
}
You can't do it using just plain Java. However, there is a Java-like language that does allow this. It's called Xtend. It compiles to Java, not bytecode, so it benefits from all the wonderful things your Java compiler does.
It started life as an Eclipse project, but is now also available for IntelliJ.
One of its many features is a thing called "Active Annotations". They do exactly what you're asking for: they allow you to participate in the code generation process, so you can insert your beginAction() and endAction() methods as you want.
See http://www.eclipse.org/xtend/documentation/204_activeannotations.html for more info on Active Annotations.
I'd like to have a reflection-like solution for displaying the methods which are called.
Example:
public class Foo {
public void bar() {
new Y().x();
}
}
public class Y {
public void x() {
}
}
public class Main {
public static void main(String[] args) {
// SETTING UP THE MAGIC
new Foo().bar();
new Y().x();
}
}
The output should be:
1. Foo.bar
1.2 Y.x
2. Y.x
Optimally there could be an event handler which would be fired every time a method is called(and some info could be passed as a parameter).
PS: I don't want to use this in a production environment, I only need this for displaying output in a skeleton app without dummy copy-paste.
I would use aspectj to define an aspect which writes log messages for every method call. You can find an example here: Tracing Java Method Execution with AspectJ. or here: Logging with AspectJ
The advantage of this solution is that you don't have to make any changes on your code. You will need some time to get into aspectj, but it meets your requirement very well.
You would have to build a profiler agent if you wanted to achieve this without having to pollute your code.
Take a look at this article, it shows you how to do it. Specifically, look at profiling aspects lower in that article.
Listing 2 is a profiling aspect that can be used to output the class name, method name, and a timestamp every time the JVM enters or leaves a method.
I'm using ASM Java library to generate a class X from scratch. Inside one of the static methods of this class I need to push a reference to X.class. Since there isn't yet a X.class I can't use visitLdcInsn. Is there a way to do it?
Well, it's possible (and I'm currently using it) to generate the following code (new X().getClass()), but I'm sure that's not the cleanest way to do it.
With generated code you usually don't need to push the class onto the stack. Anything you can do with a method call is usually available in byte code.
Say you have to call a method with a class, you can push it onto the stack whether it exists or not.
Something I use is the ASMifier. This is useful because you can start with a class which compiles and does what you want as a template and get it to dump all the code needed to recreate the class. This means you don't really need to write most of the code yourself.
public class Main {
public static void main(String... args) throws IOException {
ASMifierClassVisitor cv = new ASMifierClassVisitor(new PrintWriter(System.out));
ClassReader cr = new ClassReader("X");
cr.accept(cv, 0);
}
}
class X {
{
System.out.println("Inside class "+X.class);
}
}
prints
// lots of code
mv.visitLdcInsn(Type.getType("LX;"));
// more code.
I would like to write a code internal to my method that print which method/class has invoked it.
(My assumption is that I can't change anything but my method..)
How about other programming languages?
EDIT: Thanks guys, how about JavaScript? python? C++?
This is specific to Java.
You can use Thread.currentThread().getStackTrace(). This will return an array of StackTraceElements.
The 2nd element in the array will be the calling method.
Example:
public void methodThatPrintsCaller() {
StackTraceElement elem = Thread.currentThread.getStackTrace()[2];
System.out.println(elem);
// rest of you code
}
If all you want to do is print out the stack trace and go hunting for the class, use
Thread.dumpStack();
See the API doc.
Justin has the general case down; I wanted to mention two special cases demonstrated by this snippit:
import java.util.Comparator;
public class WhoCalledMe {
public static void main(String[] args) {
((Comparator)(new SomeReifiedGeneric())).compare(null, null);
new WhoCalledMe().new SomeInnerClass().someInnerMethod();
}
public static StackTraceElement getCaller() {
//since it's a library function we use 3 instead of 2 to ignore ourself
return Thread.currentThread().getStackTrace()[3];
}
private void somePrivateMethod() {
System.out.println("somePrivateMethod() called by: " + WhoCalledMe.getCaller());
}
private class SomeInnerClass {
public void someInnerMethod() {
somePrivateMethod();
}
}
}
class SomeReifiedGeneric implements Comparator<SomeReifiedGeneric> {
public int compare(SomeReifiedGeneric o1, SomeReifiedGeneric o2) {
System.out.println("SomeRefiedGeneric.compare() called by: " + WhoCalledMe.getCaller());
return 0;
}
}
This prints:
SomeRefiedGeneric.compare() called by: SomeReifiedGeneric.compare(WhoCalledMe.java:1)
somePrivateMethod() called by: WhoCalledMe.access$0(WhoCalledMe.java:14)
Even though the first is called "directly" from main() and the second from SomeInnerClass.someInnerMethod(). These are two cases where there is a transparent call made in between the two methods.
In the first case, this is because we are calling the bridge method to a generic method, added by the compiler to ensure SomeReifiedGeneric can be used as a raw type.
In the second case, it is because we are calling a private member of WhoCalledMe from an inner class. To accomplish this, the compiler adds a synthetic method as a go-between to override the visibility problems.
the sequence of method calls is located in stack. this is how you get the stack: Get current stack trace in Java then get previous item.
Since you asked about other languages, Tcl gives you a command (info level) that lets you examine the call stack. For example, [info level -1] returns the caller of the current procedure, as well as the arguments used to call the current procedure.
In Python you use the inspect module.
Getting the function's name and file name is easy, as you see in the example below.
Getting the function itself is more work. I think you could use the __import__ function to import the caller's module. However you must somehow convert the filename to a valid module name.
import inspect
def find_caller():
caller_frame = inspect.currentframe().f_back
print "Called by function:", caller_frame.f_code.co_name
print "In file :", caller_frame.f_code.co_filename
#Alternative, probably more portable way
#print inspect.getframeinfo(caller_frame)
def foo():
find_caller()
foo()
Yes, it is possible.
Have a look at Thread.getStackTrace()
In Python, you should use the traceback or inspect modules. These will modules will shield you from the implementation details of the interpreter, which can differ even today (e.g. IronPython, Jython) and may change even more in the future. The way these modules do it under the standard Python interpreter today, however, is with sys._getframe(). In particular, sys._getframe(1).f_code.co_name provides the information you want.