inheriting a main method

Discussion in 'Java' started by Ross, Sep 14, 2009.

  1. Ross

    Ross Guest

    I would like to write a base class from which child classes inherit a
    public static void main( String args[] ) method.

    As readers can probably guess, but problem is that the main method
    doesn't know which class to create to start the program running.

    The parent class is called Game. I can't write a method:

    public static void main( String args[] )
    {
    Game g = new Game();
    g.setVisible( true );
    }

    as it runs the base class.

    At present I have a method (simplified, from memory) which takes the
    name of the class as a runtime argument. E.g.

    public static void main( String args[] ) throws Exception
    {
    Class c = Class.forName( args[0] );
    Game g = (Game) c.newInstance();
    g.setVisible( true );
    }

    This works, but requires the name of the class to be given as an
    argument. If I could find out the name of the class that had been
    executed, then I could solve this problem. But I've looked in the
    System class properties, I've looked in Runtime, and I haven't found
    anything.

    Is there a solution to this problem? I would like the solution to be
    cross-platform.
    Ross, Sep 14, 2009
    #1
    1. Advertising

  2. Ross

    Roedy Green Guest

    On Mon, 14 Sep 2009 03:26:07 -0700 (PDT), Ross <>
    wrote, quoted or indirectly quoted someone who said :

    >I would like to write a base class from which child classes inherit a
    >public static void main( String args[] ) method.


    You naturally inherit all static methods, including main.

    You can specify which generation you want by prefixing the class name.

    e.g. Grandma.main Mom.main Me.main

    If there is no Me.main, you can use Me.main to get an Mom.main.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "The telephone is the greatest single enemy of scholarship; for what our intellectual forebears used to inscribe in ink now goes once over a wire into permanent oblivion."
    ~ Dr. Stephen Jay Gould (born: 1941-09-10 died: 2002-05-02 at age: 60)
    Roedy Green, Sep 14, 2009
    #2
    1. Advertising

  3. Roedy Green <> wrote:
    >> I would like to write a base class from which child classes inherit a
    >> public static void main( String args[] ) method.

    > You naturally inherit all static methods, including main.
    > You can specify which generation you want by prefixing the class name.
    >
    > e.g. Grandma.main Mom.main Me.main
    > If there is no Me.main, you can use Me.main to get an Mom.main.


    The real question was (as far as I understood it):

    Can the implementation of Mom.main() find out, whether the user
    used "Mom" or "Me" as startup class? Or perhaps even "Brother"
    or "Sister", which for the sake of this example also do not have
    their own main() but fall back to Mummy's?

    I don't know any way, and I doubt there even is one, but can't say
    for sure. Perhaps Java can be asked for the startup-class directly?
    Andreas Leitgeb, Sep 14, 2009
    #3
  4. On Sep 14, 2:00 pm, Andreas Leitgeb <>
    wrote:
    > Roedy Green <> wrote:
    > >> I would like to write a base class from which child classes inherit a
    > >> public static void main( String args[] ) method.

    > > You naturally inherit all static methods, including main.
    > > You can specify which generation you want by prefixing the class name.

    >
    > > e.g. Grandma.main  Mom.main Me.main
    > > If there is no Me.main, you can use Me.main to get an Mom.main.

    >
    > The real question was (as far as I understood it):
    >
    > Can the implementation of Mom.main() find out, whether the user
    > used "Mom" or "Me" as startup class?  Or perhaps even "Brother"
    > or "Sister", which for the sake of this example also do not have
    > their own main() but fall back to Mummy's?


    The real answer is: even if it can, it shouldn't. The OP should really
    refactor the code. If a custom launch protocol is desired, write it
    explicitly. Something as:

    java my.own.Game -game PacMan
    (searches for class PacMan in default package my.own.games and invokes
    main() or whatever)

    java my.own.Game -game org.foobar.FooTetris
    (searches for fully qualified class org.foobar.FooTetris and does as
    above)

    then if that's too verbose you can hide it in a (platform specific)
    shell script.

    Alessio
    Alessio Stalla, Sep 14, 2009
    #4
  5. Ross

    Ross Guest

    Thanks, but that doesn't quite work as intended. I have written two
    classes:

    public class Test
    {
    public static void main( String args[] )
    {
    Thread mainThread = Thread.currentThread();
    StackTraceElement[] currentStack = mainThread.getStackTrace();
    StackTraceElement mainStackElement = currentStack
    [ currentStack.length - 1 ];

    System.out.println( "My main class is " +
    mainStackElement.getClassName() );
    }
    }

    That works fine if I run it, and reports the class as "Test". But I
    then create a child class.

    public class Test2 extends Test
    {
    }

    If I then run:

    $ java Test2

    I get the output:

    My main class is Test

    When what I want is:

    My main class is Test2

    Any ideas on how to find out the name of the executed class rather
    than the ancestor class which has the main method?
    Ross, Sep 14, 2009
    #5
  6. Ross

    Ross Guest

    I could probably solve the problem if I could find a list of the
    classes that are currently loaded. As only one of them will be an
    instance of "Game", apart from "Game" (my parent class) itself. But
    looking through the classloader interface, I can't seem to find that
    out either.
    Ross, Sep 14, 2009
    #6
  7. Ross

    Ross Guest

    On Sep 14, 3:48 pm, Leif Roar Moldskred
    <> wrote:
    > Ow. Don't do that. For one thing, I don't think there _is_ any way
    > to retrieve the name of the class mentioned on the command line
    > in this case. More importantly, it's bad design.
    >
    > I'd recommend you make an inherited business method, then write
    > explicit main methods for all the classes that will use it (There
    > can't be _that_ many of them, and it make it a lot easier to
    > understand what's happening.)
    >
    > Something like this:
    >
    > public abstract class BaseClass {
    > protected void doStuff( String[] args ) {
    > // Do whatever you're supposed to do
    > }
    >
    > }
    >
    > public class SubClass extends BaseClass {
    > public static void main( String[] args ) {
    > BaseClass myFoo = new SubClass( );
    > myFoo.doStuff( args );
    > }
    >
    > }
    >
    > If you have common initialization that needs to be done, use an
    > inherited initialization method as well:
    >
    > public static void main( String[] args ) {
    > BaseClass myFoo = new SubClass( );
    > myFoo.initialize( args );
    > myFoo.doStuff( );
    > }


    Unfortunately, I need to do this. The parent class is going to be
    subclassed by young children, first experimental subject being a nine
    year old. I have to kick out the main class, but still have it
    runnable. Fundamentally, you can't teach advanced programming
    languages with sophisticated structures to young children, or at least
    most young children. I'm sure there are some prodigies out there.
    Previously when I've done this before, I've created bespoke
    programming languages with bespoke IDEs. But the whole point of what
    I'm trying now is to see whether Object Orientated Programming can be
    leveraged to produce a LOGO style language (and execution environment)
    while the code being written is actually proper Java, just extending a
    prewritten class.

    The alternative is to modify the IDE that will be used to supply the
    name of the class as the first argument to the running program. I
    don't particularly want to modify the IDE, as that means that the IDE
    would become a necessary part of the environment, but it is currently
    the best solution, and I don't appear to be finding anything better
    than that.

    Thanks for all for the comments and ideas.
    Ross, Sep 14, 2009
    #7
  8. On Sep 14, 4:54 pm, Ross <> wrote:
    > I could probably solve the problem if I could find a list of the
    > classes that are currently loaded. As only one of them will be an
    > instance of "Game", apart from "Game" (my parent class) itself. But
    > looking through the classloader interface, I can't seem to find that
    > out either.


    If only one game at a time can be loaded (this wasn't apparent from
    your first post), you can use a factory to create it. E.g. you can use
    the standard service provider machinery: <http://java.sun.com/j2se/1.3/
    docs/guide/jar/jar.html#Service%20Provider> or a custom solution.

    hth,
    Alessio
    Alessio Stalla, Sep 14, 2009
    #8
  9. Ross

    Ross Guest

    On Sep 14, 3:48 pm, Leif Roar Moldskred
    <> wrote:
    > I'd recommend you make an inherited business method, then write
    > explicit main methods for all the classes that will use it (There
    > can't be _that_ many of them, and it make it a lot easier to
    > understand what's happening.)


    But, I want to deliver a system where the end user will make up their
    own classes. Hence i can't pre-write methods without constraining the
    end user to a relatively short list of possible class names.
    Ross, Sep 14, 2009
    #9
  10. If I understand the problem, the user runs

    java classname

    where classname has a superclass that defines the main(String[])
    method, and you want it to figure out what "classname" is. This can't
    be done.

    However, if you change the command to

    java mainclass classname

    where classname, instead of subclassing mainclass, implements some
    known interface, it becomes trivial. (mainclass.main() calls
    class.forName().newInstance() on its argument, but you knew that.)
    Mike Schilling, Sep 14, 2009
    #10
  11. Ross

    markspace Guest

    Ross wrote:

    > Previously when I've done this before, I've created bespoke
    > programming languages with bespoke IDEs. But the whole point of what
    > I'm trying now is to see whether Object Orientated Programming can be



    I'm still more than a little confused about what you want the final
    result to look like. Do you want a command line? An IDE? Something
    different?


    > The alternative is to modify the IDE that will be used to supply the
    > name of the class as the first argument to the running program.



    This could be done pretty easily in NetBeans by setting the default
    template for a new class, and turning on code folding. The kids will
    not see the boilerplate code supplied by the IDE within the code folds.

    You also might be able to use a custom Ant script. I'm not sure about
    generating one on a new project though.
    markspace, Sep 14, 2009
    #11
  12. Ross

    Daniel Pitts Guest

    Ross wrote:
    > I could probably solve the problem if I could find a list of the
    > classes that are currently loaded. As only one of them will be an
    > instance of "Game", apart from "Game" (my parent class) itself. But
    > looking through the classloader interface, I can't seem to find that
    > out either.

    You could also have your main in a *different* class than the one being
    subclassed, and then pass the "Game Class Name" as a separate query
    argument.

    Also, It could be a requirement that your Game class does *not* supply a
    main method, but instead make the "main method" easy to write.
    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
    Daniel Pitts, Sep 14, 2009
    #12
  13. Ross

    Arne Vajhøj Guest

    Andreas Leitgeb wrote:
    > Roedy Green <> wrote:
    >>> I would like to write a base class from which child classes inherit a
    >>> public static void main( String args[] ) method.

    >> You naturally inherit all static methods, including main.
    >> You can specify which generation you want by prefixing the class name.
    >>
    >> e.g. Grandma.main Mom.main Me.main
    >> If there is no Me.main, you can use Me.main to get an Mom.main.

    >
    > The real question was (as far as I understood it):
    >
    > Can the implementation of Mom.main() find out, whether the user
    > used "Mom" or "Me" as startup class? Or perhaps even "Brother"
    > or "Sister", which for the sake of this example also do not have
    > their own main() but fall back to Mummy's?
    >
    > I don't know any way, and I doubt there even is one, but can't say
    > for sure. Perhaps Java can be asked for the startup-class directly?


    If we can assume that Java version >= 1.5, main thread has
    thread id 1 and max. stack depth is 1000:

    StackTraceElement[] ste =
    ManagementFactory.getThreadMXBean().getThreadInfo(1, 1000).getStackTrace();
    String clznam = ste[ste.length-1].getClassName();

    Arne
    Arne Vajhøj, Sep 15, 2009
    #13
  14. Arne Vajhøj wrote:
    > Andreas Leitgeb wrote:
    >> Roedy Green <> wrote:
    >>>> I would like to write a base class from which child classes
    >>>> inherit a public static void main( String args[] ) method.
    >>> You naturally inherit all static methods, including main.
    >>> You can specify which generation you want by prefixing the class
    >>> name. e.g. Grandma.main Mom.main Me.main
    >>> If there is no Me.main, you can use Me.main to get an Mom.main.

    >>
    >> The real question was (as far as I understood it):
    >>
    >> Can the implementation of Mom.main() find out, whether the user
    >> used "Mom" or "Me" as startup class? Or perhaps even "Brother"
    >> or "Sister", which for the sake of this example also do not have
    >> their own main() but fall back to Mummy's?
    >>
    >> I don't know any way, and I doubt there even is one, but can't say
    >> for sure. Perhaps Java can be asked for the startup-class directly?

    >
    > If we can assume that Java version >= 1.5, main thread has
    > thread id 1 and max. stack depth is 1000:
    >
    > StackTraceElement[] ste =
    > ManagementFactory.getThreadMXBean().getThreadInfo(1,
    > 1000).getStackTrace(); String clznam =
    > ste[ste.length-1].getClassName();


    Is that really going to give you the class mentioned in the command line
    rather than the class which defines the static main() method?
    Mike Schilling, Sep 15, 2009
    #14
  15. Ross

    Arne Vajhøj Guest

    Mike Schilling wrote:
    > Arne Vajhøj wrote:
    >> Andreas Leitgeb wrote:
    >>> Roedy Green <> wrote:
    >>>>> I would like to write a base class from which child classes
    >>>>> inherit a public static void main( String args[] ) method.
    >>>> You naturally inherit all static methods, including main.
    >>>> You can specify which generation you want by prefixing the class
    >>>> name. e.g. Grandma.main Mom.main Me.main
    >>>> If there is no Me.main, you can use Me.main to get an Mom.main.
    >>> The real question was (as far as I understood it):
    >>>
    >>> Can the implementation of Mom.main() find out, whether the user
    >>> used "Mom" or "Me" as startup class? Or perhaps even "Brother"
    >>> or "Sister", which for the sake of this example also do not have
    >>> their own main() but fall back to Mummy's?
    >>>
    >>> I don't know any way, and I doubt there even is one, but can't say
    >>> for sure. Perhaps Java can be asked for the startup-class directly?

    >> If we can assume that Java version >= 1.5, main thread has
    >> thread id 1 and max. stack depth is 1000:
    >>
    >> StackTraceElement[] ste =
    >> ManagementFactory.getThreadMXBean().getThreadInfo(1,
    >> 1000).getStackTrace(); String clznam =
    >> ste[ste.length-1].getClassName();

    >
    > Is that really going to give you the class mentioned in the command line
    > rather than the class which defines the static main() method?


    You are correct. It returns the parent class where main is
    defined.

    Arne
    Arne Vajhøj, Sep 15, 2009
    #15
  16. Arne Vajhøj wrote:
    >>> If we can assume that Java version >= 1.5, main thread has
    >>> thread id 1 and max. stack depth is 1000:
    >>>
    >>> StackTraceElement[] ste =
    >>> ManagementFactory.getThreadMXBean().getThreadInfo(1,
    >>> 1000).getStackTrace(); String clznam =
    >>> ste[ste.length-1].getClassName();

    >>
    >> Is that really going to give you the class mentioned in the command
    >> line rather than the class which defines the static main() method?

    >
    > You are correct. It returns the parent class where main is
    > defined.


    Right. My strong impression is that trying to figure out which subclass was
    mentioned in the command line is simply hopeless (or at best extremely
    non-portable) and that, accordingly, the OP should figure out some other way
    of doing things. Fortunately, there are dozens of them.
    Mike Schilling, Sep 15, 2009
    #16
  17. Ross

    Mike Amling Guest

    Ross wrote:
    > I could probably solve the problem if I could find a list of the
    > classes that are currently loaded. As only one of them will be an
    > instance of "Game", apart from "Game" (my parent class) itself. But
    > looking through the classloader interface, I can't seem to find that
    > out either.


    Your students are already compiling their code with some boilerplate,
    namely

    class Mine extends Game {
    ....
    }

    Could you change that boilerplate to invoke a constructor in Game via an
    implicit super(), and have the Game constructors leave what you need in
    one of Game's static variables where Game.main can find it?

    class Mine extends Game {
    static {new Mine();}
    ....
    }

    --Mike Amling
    Mike Amling, Sep 15, 2009
    #17
  18. Ross

    Ross Guest

    On Sep 15, 1:06 am, Arne Vajhøj <> wrote:
    > If we can assume that Java version >= 1.5, main thread has
    > thread id 1 and max. stack depth is 1000:
    >
    > StackTraceElement[] ste =
    > ManagementFactory.getThreadMXBean().getThreadInfo(1, 1000).getStackTrace();
    > String clznam = ste[ste.length-1].getClassName();
    >
    > Arne


    That doesn't work, it always gives the name of the class where main is
    declared, not the subclass.
    Ross, Sep 15, 2009
    #18
  19. Ross

    Ross Guest

    On Sep 15, 4:04 am, Mike Amling <> wrote:
    > Could you change that boilerplate to invoke a constructor in Game via an
    > implicit super(), and have the Game constructors leave what you need in
    > one of Game's static variables where Game.main can find it?
    >
    > class Mine extends Game {
    > static {new Mine();}
    > ...
    >
    > }



    I could do that, but I think it's more confusing than what I'm going
    now.

    I've thought about this a bit, and had one go at getting the child to
    program in the language. The biggest problem was forgetting to put
    semicolons after commands. Because while "proper java" is being
    written, methods from the Game class are being used that makes it look
    like a "Logo" like language. Because what is being written is limited,
    it will be easy to write code into the IDE that looks for common
    errors and gives human-like advice. Hence, I'll modify the IDE anyhow,
    and making my initial solution work (give the name of the class as an
    argument) is easy.

    The IDE I'm using is a very basic IDE written by a colleague of mine
    at work. I have all the source code.
    Ross, Sep 15, 2009
    #19
  20. Ross

    Arne Vajhøj Guest

    Ross wrote:
    > On Sep 15, 1:06 am, Arne Vajhøj <> wrote:
    >> If we can assume that Java version >= 1.5, main thread has
    >> thread id 1 and max. stack depth is 1000:
    >>
    >> StackTraceElement[] ste =
    >> ManagementFactory.getThreadMXBean().getThreadInfo(1, 1000).getStackTrace();
    >> String clznam = ste[ste.length-1].getClassName();

    >
    > That doesn't work, it always gives the name of the class where main is
    > declared, not the subclass.


    True.

    Mike Schilling already pointed that out.

    Arne
    Arne Vajhøj, Sep 18, 2009
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John M
    Replies:
    1
    Views:
    1,115
    Kumar Reddi
    May 29, 2005
  2. Hal Styli
    Replies:
    14
    Views:
    1,615
    Old Wolf
    Jan 20, 2004
  3. Frederick Ding

    int main() or int main(void)?

    Frederick Ding, Dec 3, 2005, in forum: C Programming
    Replies:
    10
    Views:
    641
  4. Ravi
    Replies:
    17
    Views:
    913
    Kenneth Brody
    Apr 1, 2006
  5. main() called inside main()

    , May 4, 2006, in forum: C Programming
    Replies:
    14
    Views:
    1,409
    Richard Heathfield
    May 7, 2006
Loading...

Share This Page