Java Forum / General / May 2006
What's java equivalent of C's argv[ 0 ]?
joseph_daniel_zukiger@yahoo.com - 14 Apr 2006 02:51 GMT 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?
au714@osfn.org - 14 Apr 2006 03:10 GMT public class MyClass { public static void main(String[] args) { System.out.println(MyClass.class.getName()); } }
Dimitri Maziuk - 15 Apr 2006 19:36 GMT au714@osfn.org 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
 Signature I have not been able to think of any way of describing Perl to [person] "Hello, blind man? This is color." -- DPM
Oliver Wong - 17 Apr 2006 18:37 GMT > au714@osfn.org sez: >> public class MyClass { [quoted text clipped - 4 lines] > > 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
Dimitri Maziuk - 18 Apr 2006 00:23 GMT Oliver Wong sez:
>> au714@osfn.org sez: >>> public class MyClass { [quoted text clipped - 15 lines] > 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
 Signature Riding roughshod over some little used trifle like the English language is not a big deal to an important technology innovator like Microsoft. They did just that by naming a major project dot-Net (".Net"). Before that, a period followed by a capital letter was used to mark a sentence boundary. --T. Gottfried, RISKS 21.91
Patricia Shanahan - 18 Apr 2006 00:52 GMT > Oliver Wong sez: > [quoted text clipped - 25 lines] > > 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
Oliver Wong - 18 Apr 2006 14:38 GMT > Oliver Wong sez: >> [quoted text clipped - 25 lines] > 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
joseph_daniel_zukiger@yahoo.com - 14 Apr 2006 03:25 GMT > 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(). [quoted text clipped - 10 lines] > > 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.
Steve W. Jackson - 17 Apr 2006 18:48 GMT > > I thought I knew this once, but maybe I was just fooling myself. > [quoted text clipped - 4 lines] > 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).
 Signature Steve W. Jackson Montgomery, Alabama
joseph_daniel_zukiger@yahoo.com - 13 May 2006 13:27 GMT > > > I thought I knew this once, but maybe I was just fooling myself. > > [quoted text clipped - 10 lines] > 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). My wife was worried that I was going to name one of the kids "Lousy". 8-(
I should note somewhere in this thread, that in the particular case I'm working on, static initializations actually get there in time to get the Application menu named.
I'm vaguely aware that I'll want to back the code out when I'm ready to build a Macintosh bundle, but it helps for now.
Patricia Shanahan - 14 Apr 2006 05:10 GMT > I thought I knew this once, but maybe I was just fooling myself. > [quoted text clipped - 12 lines] > > 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
joseph_daniel_zukiger@yahoo.com - 25 Apr 2006 05:00 GMT > > I thought I knew this once, but maybe I was just fooling myself. > > [quoted text clipped - 32 lines] > 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
joseph_daniel_zukiger@yahoo.com - 26 Apr 2006 02:25 GMT > > > I thought I knew this once, but maybe I was just fooling myself. > > > [quoted text clipped - 25 lines] > 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();
}
Eric Sosman - 26 Apr 2006 15:07 GMT joseph_daniel_zukiger@yahoo.com wrote On 04/25/06 21:25,:
> [...] > The problems with setting the Mac OS X application menu name from [quoted text clipped - 3 lines] > 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?)
 Signature Eric.Sosman@sun.com
Oliver Wong - 26 Apr 2006 17:41 GMT > (No, the existence of multiple main() methods is not > a mere perversity. For example, consider the usual way [quoted text clipped - 4 lines] > 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
Roedy Green - 26 Apr 2006 18:57 GMT > (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.
 Signature Canadian Mind Products, Roedy Green. http://mindprod.com Java custom programming, consulting and coaching.
Eric Sosman - 26 Apr 2006 19:35 GMT Roedy Green wrote On 04/26/06 13:57,:
>> (No, the existence of multiple main() methods is not >>a mere perversity [quoted text clipped - 9 lines] > 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 ...
 Signature Eric.Sosman@sun.com
Oliver Wong - 26 Apr 2006 21:36 GMT > 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
Owen Jacobson - 28 Apr 2006 02:39 GMT >> 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 [quoted text clipped - 4 lines] > 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.
Oliver Wong - 28 Apr 2006 18:11 GMT >>> 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 [quoted text clipped - 7 lines] > > Provided you're still in the same thread main is executing in, anyways. Damn, you got me there.
Maybe have some sort of synchronized Singleton which takes a Throwable as part of its instantiation? All entry points to the program would "try" to initialize the Singleton by generating a Throwable (and thus a stack trace) and pass it on to the Singleton, who would ignore all such initializations except for the first one, thus guaranteeing that it has the trace that corresponds to the original entry point?
Of course, by using a Singleton, this assumes no funny business with the class loader...
- Oliver
Chris Uppal - 27 Apr 2006 10:19 GMT > 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
joseph_daniel_zukiger@yahoo.com - 13 May 2006 13:23 GMT > Roedy Green wrote On 04/26/06 13:57,: > > [quoted text clipped - 15 lines] > identify "the program" by picking out the name of one of its > many classes is likely to fail. Well, I did try to point out at the beginning of the thread that I am aware of the reasons it makes much less sense in the Java world. But it does make sense in the program I am working on, if only for now.
I'm not sure if it will make sense by the time I have it complete enough to call it a product. I just want a simple way to see in the Machintosh menu bar which command line I invoked to get the thing running this time. And I don't want to go to the trouble of building a Macintosh bundle, which is the preferred place to specify the -D property which becomes the Application menu name.
(The Application menu is, at present, more-or-less unique to the Mac OS X GUI run-time, so the code in question is conditional to running under Mac OS X. Well, the name is collected on all platforms, but only used on the Mac under OS X, the way I have it now.)
> 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. I'm not sure I agree with the argument, as it asserts as the primary C programming context a family of technologies which I don't recognize as valid. But I still see a utility in allowing any Class with a main() method to publish a uniquely identifying name.
> 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 ... So you don't use it if it's not useful. That's fine with me, especially since I now know there is a way to do it without creating implicit semantic bindings. I don't particularly care that it takes a little extra code, as long as I know that the code, once in place, won't get out of sync even if I rename the class using a plain old text editor. That was my primary concern for starting this thread, and I do appreciate all the comments.
Thomas Schodt - 18 Apr 2006 16:04 GMT > 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()); }
}
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|