What's java equivalent of C's argv[ 0 ]?

  • Thread starter joseph_daniel_zukiger
  • Start date
J

joseph_daniel_zukiger

I thought I knew this once, but maybe I was just fooling myself.

this.getClass().getName() doesn't work from static methods, so it
doesn't work from main().

The reason I want to do such a silly thing is that I don't want to go
looking for the bare string "MainClass" when I decide to change the
name of the MainClass to something a little more descriptive, like,
ProjectA or something. I need it to tell Mac OS X what to call the
application menu from within the program. (I know this is not what
Apple recommends.)

Checking Google dug up a thread on GCJ, with a proposed
gnu.gcj.progname property.

Can this be done in standard Java?
 
A

au714

public class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getName());
}
}
 
J

joseph_daniel_zukiger

I thought I knew this once, but maybe I was just fooling myself.

erk.

I just reminded myself of why this is not the way to do things.

By the time main can install the property, Apple's runtime apparently
has already set the lousy application menu name.
this.getClass().getName() doesn't work from static methods, so it
doesn't work from main().

The reason I want to do such a silly thing is that I don't want to go
looking for the bare string "MainClass" when I decide to change the
name of the MainClass to something a little more descriptive, like,
ProjectA or something. I need it to tell Mac OS X what to call the
application menu from within the program. (I know this is not what
Apple recommends.)

Checking Google dug up a thread on GCJ, with a proposed
gnu.gcj.progname property.

Can this be done in standard Java?

I did find some good pages with this query:

http://www.google.com/search?q=apple+application+menu+name

including

http://java.sun.com/developer/technicalArticles/JavaLP/JavaToMac/

and some of Apple's pages with very long URLs.
 
P

Patricia Shanahan

I thought I knew this once, but maybe I was just fooling myself.

this.getClass().getName() doesn't work from static methods, so it
doesn't work from main().

The reason I want to do such a silly thing is that I don't want to go
looking for the bare string "MainClass" when I decide to change the
name of the MainClass to something a little more descriptive, like,
ProjectA or something. I need it to tell Mac OS X what to call the
application menu from within the program. (I know this is not what
Apple recommends.)

Checking Google dug up a thread on GCJ, with a proposed
gnu.gcj.progname property.

Can this be done in standard Java?

Here's one way:

public class TestNaming {
public static void main(String[] args) {
System.out.println(new NameGetter().getName());
}
static class NameGetter{
String getName(){
return getClass().getDeclaringClass().getName();
}
}
}

This is not strictly a replacement for argv[0]. It only tells you the
name of the class in which the NameGetter is declared. For example, if I
called that main() method in another program, it would still report
"TestNaming". Each class for which you want to be able to get the name
from static contexts must declare its own NameGetter as a static nested
class.

A refactoring tool should solve the problem of name changing
without doing this sort of thing.

Patricia
 
D

Dimitri Maziuk

(e-mail address removed) sez:
public class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getName());
}
}

where ".class.getName()" is completely redundant.

To OP: main() doesn't have argv[0] for the same reason it does
not return an int. What you use if you want to change the name
of your class is the advanced refactoring technique called
"search and replace".

Dima
 
O

Oliver Wong

Dimitri Maziuk said:
(e-mail address removed) sez:
public class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getName());
}
}

where ".class.getName()" is completely redundant.
[...]
What you use if you want to change the name
of your class is the advanced refactoring technique called
"search and replace".

Eclipse's refactoring engine is a bit reluctant to make changes inside
the contents of string literals, though. When I want to have the name of the
class, I use something similar to the above code. Since there are no string
literals involved, the refactoring engine will "do the right thing" when you
rename your class.

- Oliver
 
S

Steve W. Jackson

erk.

I just reminded myself of why this is not the way to do things.

By the time main can install the property, Apple's runtime apparently
has already set the lousy application menu name.

Then I needn't bother sending the reply I had planned to tell you
exactly that...

Of course, I also won't tell you that I'd never use an application named
"lousy"...(I know, I'll never make it in comedy).
 
D

Dimitri Maziuk

Oliver Wong sez:
Dimitri Maziuk said:
(e-mail address removed) sez:
public class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getName());
}
}

where ".class.getName()" is completely redundant.
[...]
What you use if you want to change the name
of your class is the advanced refactoring technique called
"search and replace".

Eclipse's refactoring engine is a bit reluctant to make changes inside
the contents of string literals, though. When I want to have the name of the
class, I use something similar to the above code. Since there are no string
literals involved, the refactoring engine will "do the right thing" when you
rename your class.

Which is what makes search and replace an advanced refactoring technique:
it will work on tokens that regular refactoring engines won't touch, such
as string literals and comments.

Dima
 
P

Patricia Shanahan

Dimitri said:
Oliver Wong sez:
(e-mail address removed) sez:

public class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getName());
}
}

where ".class.getName()" is completely redundant.

[...]

What you use if you want to change the name
of your class is the advanced refactoring technique called
"search and replace".

Eclipse's refactoring engine is a bit reluctant to make changes inside
the contents of string literals, though. When I want to have the name of the
class, I use something similar to the above code. Since there are no string
literals involved, the refactoring engine will "do the right thing" when you
rename your class.


Which is what makes search and replace an advanced refactoring technique:
it will work on tokens that regular refactoring engines won't touch, such
as string literals and comments.

Dima

Eclipse rename does quite a nice job. The only reluctance I saw was that
enabling text replacement in strings and comments turns on the preview
feature, but I think I would want it anyway.

Patricia
 
O

Oliver Wong

Dimitri Maziuk said:
Oliver Wong sez:
Dimitri Maziuk said:
(e-mail address removed) sez:
public class MyClass {
public static void main(String[] args) {
System.out.println(MyClass.class.getName());
}
}

where ".class.getName()" is completely redundant.
[...]
What you use if you want to change the name
of your class is the advanced refactoring technique called
"search and replace".

Eclipse's refactoring engine is a bit reluctant to make changes
inside
the contents of string literals, though. When I want to have the name of
the
class, I use something similar to the above code. Since there are no
string
literals involved, the refactoring engine will "do the right thing" when
you
rename your class.

Which is what makes search and replace an advanced refactoring technique:
it will work on tokens that regular refactoring engines won't touch, such
as string literals and comments.

A string-based search and replace will "do the wrong thing" if you have
MyClass as a substring of other tokens, or if you have two classes (in
different packages) called MyClass, for example. There are probably other
cases where string-based search and replace will do the wrong thing, which
is why I never use that feature, and always do a parse-based refactoring.

- Oliver
 
T

Thomas Schodt

this.getClass().getName() doesn't work from static methods

class Whatever {
private static final Class myClass = new SecurityManager() {
public Class getClass1(){return getClassContext()[1];}
}.getClass1();
public static Class getClass1() { return myClass; }

public static final void main(String[] arg) {
System.out.println(getClass1().getName());
}

}
 
J

joseph_daniel_zukiger

Patricia said:
I thought I knew this once, but maybe I was just fooling myself.

this.getClass().getName() doesn't work from static methods, so it
doesn't work from main().

The reason I want to do such a silly thing is that I don't want to go
looking for the bare string "MainClass" when I decide to change the
name of the MainClass to something a little more descriptive, like,
ProjectA or something. I need it to tell Mac OS X what to call the
application menu from within the program. (I know this is not what
Apple recommends.)

Checking Google dug up a thread on GCJ, with a proposed
gnu.gcj.progname property.

Can this be done in standard Java?

Here's one way:

public class TestNaming {
public static void main(String[] args) {
System.out.println(new NameGetter().getName());
}
static class NameGetter{
String getName(){
return getClass().getDeclaringClass().getName();
}
}
}

This is not strictly a replacement for argv[0]. It only tells you the
name of the class in which the NameGetter is declared. For example, if I
called that main() method in another program, it would still report
"TestNaming". Each class for which you want to be able to get the name
from static contexts must declare its own NameGetter as a static nested
class.

It looks like it does the job for what I had in mind, if only what I
had in mind would have worked.
A refactoring tool should solve the problem of name changing
without doing this sort of thing.

Patricia

Maybe it's because I'm more of a C programmer (I think we once
disagreed on fine points concerning the use of ++i and i++?) and don't
see things the same way as many Java programmers, but I prefer not to
ask such things of my refactoring tools. I suppose I'm being a little
analytic compulsive about decoupling, but I like my semantics bound in
the expression rather than in the use of external tools.

Much grass.

jdz
 
J

joseph_daniel_zukiger

Patricia said:
I thought I knew this once, but maybe I was just fooling myself.

this.getClass().getName() doesn't work from static methods, so it
doesn't work from main().

[...]

Here's one way:

public class TestNaming {
public static void main(String[] args) {
System.out.println(new NameGetter().getName());
}
static class NameGetter{
String getName(){
return getClass().getDeclaringClass().getName();
}
}
}

This is not strictly a replacement for argv[0]. It only tells you the
name of the class in which the NameGetter is declared. For example, if I
called that main() method in another program, it would still report
"TestNaming". Each class for which you want to be able to get the name
from static contexts must declare its own NameGetter as a static nested
class.

It looks like it does the job for what I had in mind, if only what I
had in mind would have worked.

The problems with setting the Mac OS X application menu name from
within Java code aside, I took Patricia Shanahan's suggestion a step
further and used static initialization to salt the fully qualified
class name away in a class variable without having to mention it in
main(). For the archives:

public class AMainClass
{
// Other things in the main class here ...

public static void main( final String[] args )
{
// ...
System.out.println( "main Class name: " + AMainClass.mainClassName );
}

/**
* argv[ 0 ]
* Courtesy of Patricia Shanahan on comp.lang.java.programmer:
*/
private static class NameGetter
{ public String getName()
{ // Returns the fully qualified class name.
return getClass().getDeclaringClass().getName();
}
}
//
public static final String mainClassName = new NameGetter().getName();

}
 
E

Eric Sosman

[...]
The problems with setting the Mac OS X application menu name from
within Java code aside, I took Patricia Shanahan's suggestion a step
further and used static initialization to salt the fully qualified
class name away in a class variable without having to mention it in
main(). For the archives:
[... see archives for snipped code ...]

Keep in mind that every Java class can have its own
`public static void main(String[])' method; by the time
your program is up and running there may be many different
main() methods lying around. The problem of figuring out
which of them is "the" main() method seems not so easy to
solve.

(No, the existence of multiple main() methods is not
a mere perversity. For example, consider the usual way
of writing Swing code that will run either as an applet
or as an application: There's a main() that gets used when
running as an application, but that is not used when the
code runs as an applet. If the code is running as an applet,
does it make sense to designate a method that's never even
called as "the" main() method?)
 
O

Oliver Wong

Eric Sosman said:
(No, the existence of multiple main() methods is not
a mere perversity. For example, consider the usual way
of writing Swing code that will run either as an applet
or as an application: There's a main() that gets used when
running as an application, but that is not used when the
code runs as an applet. If the code is running as an applet,
does it make sense to designate a method that's never even
called as "the" main() method?)

I thought the standard pattern for this sort of stuff is to have your
main method create a JWindow, add the JApplet to the JWindow, and call the
init() and start() method. So either the init() or the start() method could
be considered "the" "main" method.

I wrote an RPG engine with a level editor. The engine and the editor
shared a lot of code, so it was made one big project with two "public static
void main(String[] args)" methods. One in a class called Game, and one in a
class called Editor. Depending on which one you called, you could either
design a new game, or play the game you just designed.

At work, we're writing and Eclipse plugin to do various source-code
analysis type stuff. We've got lots of "public static void main(String[]
args)" methods so that each functionality can be tested at the command line
(or within unit tests). For example, there's an entry point where you can
pass in a input filename and an output filename, and it'll parse the input
file and dump the abstract syntax tree generated as an XML document to the
output filename. This is to test that the input files are correctly being
parsed, although that isn't the "main" goal of the plugin.

- Oliver
 
R

Roedy Green

(No, the existence of multiple main() methods is not
a mere perversity

Other uses of multiple main methods:

1. a test driver method on each class to help debug and test it in
isolation.

2. various canned setups that call the generic main so you don't need
an elaborate generated command line.

3. Use the same jar to do several different things. It is a utility
suite.
 
E

Eric Sosman

Roedy Green wrote On 04/26/06 13:57,:
Other uses of multiple main methods:

1. a test driver method on each class to help debug and test it in
isolation.

2. various canned setups that call the generic main so you don't need
an elaborate generated command line.

3. Use the same jar to do several different things. It is a utility
suite.

And the list goes on. My point is that the attempt to
identify "the program" by picking out the name of one of its
many classes is likely to fail. There really isn't such a
thing as "the program" in Java; there's just a collection of
classes the JVM happens to load, and that collection can vary
from one run to the next. There's no "there" there, not in
the same way there is for a statically-linked language.

There might be a way to learn the name of the class the
JVM was told to load when it first started up, but even that
could turn out to be uninformative. If you learned that "the
program" was com.tools.java.debuggers.CoverageAnalyzer, the
information might not be of a lot of use ...
 
O

Oliver Wong

Eric Sosman said:
There might be a way to learn the name of the class the
JVM was told to load when it first started up, but even that
could turn out to be uninformative. If you learned that "the
program" was com.tools.java.debuggers.CoverageAnalyzer, the
information might not be of a lot of use ...

Right. You could generate a stack trace and then analyze it, going down
the list, and keep track of the last package you saw that was "yours".

- Oliver
 
C

Chris Uppal

Eric said:
My point is that the attempt to
identify "the program" by picking out the name of one of its
many classes is likely to fail. There really isn't such a
thing as "the program" in Java; there's just a collection of
classes the JVM happens to load, and that collection can vary
from one run to the next.

For the C or C++ programmer -- at least one used to using DLLs (or equivalent)
properly -- it's as if the "program" is just a hard-disk full of thousands and
thousands of DLLs, plus a single, fixed, 10-line launcher program which reads
the name of one DLL from its command-line.

-- chris
 
O

Owen Jacobson

Right. You could generate a stack trace and then analyze it, going down
the list, and keep track of the last package you saw that was "yours".

Provided you're still in the same thread main is executing in, anyways.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,433
Messages
2,571,683
Members
48,796
Latest member
Greg L.

Latest Threads

Top