Reputation: 4062
I have found following question: $0 (Program Name) in Java? Discover main class? but accepted answer fails in this situation:
public class Derived extends Base { }
class Base {
public static void main(String[] args){
System.out.println(getTheClassName());
}
static String getTheClassName(){
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
StackTraceElement main = stack[stack.length - 1];
return main.getClassName();
}
}
When calling:
java Derived
the output is unfortunately Base
not Derived
as expected.
Is it possible to get the name of real main class? (btw. jps
tool detects main class correctly but to get the proper name I need to know ID of current VM, and that is also a problem)
Best regards.
Edit: to be precise: I need to know what is the name of class passed as command line argument passed to JVM. jps
tools does it the way I want, but I cannot use this tool because of other problems (such as unknown VMid).
Edit2: replying globally to Thorbjørn's answer:
For your approach to work, you need to have a non-static method instead. Make it non-static, have a main() in Derived doing a new Derived().getTheClassName()
I am wondering I can get the name without implementing main method in Derived class.
Solution: I will provide both (Thorbjørn's and erickson's) mechanisms of an initialization of Derived
class ;-) All of the answers were very helpful. I accepted Thorbjørn's becase he posted his answer earlier than erickson. Thank You.
Upvotes: 2
Views: 4694
Reputation: 269647
Why would you expect Derived
when the main
entry-point is in Base
? Members that are declared static
belong to their class and are not inherited. When running the program as is, the class Derived
will not even be loaded, as it is never referenced.
Consider taking the derived class's name as an argument to the Base
class. In addition to making the target class explicit, it might be a convenient place to implement other features.
class Base {
public static void main(String... argv) throws Exception {
Class<?> clz = Class.forName(argv[0]);
Method mth = clz.getMethod("main", String[].class);
String[] sub = new String[argv.length - 1];
System.arraycopy(argv, 1, sub, 0, sub.length);
mth.invoke(null, sub);
}
}
Upvotes: 3
Reputation: 93157
Try this:
for(final Map.Entry<String, String> entry : System.getenv().entrySet()){
if(entry.getKey().startsWith("JAVA_MAIN_CLASS"))
return entry.getValue();
}
But still you should look at others answers. Even if this works, it's a really bad practice.
Upvotes: 1
Reputation: 75356
Static methods belong to the class they are defined in, and not the instance of the class (same as static/non-static methods). Hence when you are inside getTheClassName you are in a static method defined in the Base class.
For your approach to work, you need to have a non-static method instead. Make it non-static, have a main() in Derived doing a new Derived().getTheClassName()
Upvotes: 5