summaryrefslogtreecommitdiff
path: root/src/library/scala/Application.scala
blob: 5b1098bd726ce7ab8fc2b217ca052b7f26c21c1b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2002-2011, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala

import scala.compat.Platform.currentTime

/** The `Application` trait can be used to quickly turn objects
 *  into executable programs, but is ''not recommended''.
 *  Here is an example:
 *  {{{
 *  object Main extends Application {
 *    Console.println("Hello World!")
 *  }
 *  }}}
 *  Here, object `Main` inherits the `main` method of `Application`.
 *  The body of the `Main` object defines the main program. This technique
 *  does not work if the main program depends on command-line arguments
 *  (which are not accessible with the technique presented here).
 *
 *  It is possible to time the execution of objects that inherit from class
 *  `Application` by setting the global `scala.time`
 *  property. Here is an example for benchmarking object `Main`:
 *  {{{
 *  java -Dscala.time Main
 *  }}}
 *  In practice the `Application` trait has a number of serious pitfalls:
 *
 *  - Threaded code that references the object will block until static
 *    initialization is complete.  However, because the entire execution
 *    of an `object` extending `Application` takes place during
 *    static initialization, concurrent code will ''always'' deadlock if
 *    it must synchronize with the enclosing object.
 *  - As described above, there is no way to obtain the
 *    command-line arguments because all code in body of an `object`
 *    extending `Application` is run as part of the static initialization
 *    which occurs before `Application`'s `main` method
 *    even begins execution.
 *  - Static initializers are run only once during program execution, and
 *    JVM authors usually assume their execution to be relatively short.
 *    Therefore, certain JVM configurations may become confused, or simply
 *    fail to optimize or JIT the code in the body of an `object` extending
 *    `Application`.  This can lead to a significant performance degradation.
 *
 *  It is recommended to use the [[scala.App]] trait instead.
 *  {{{
 *  object Main {
 *    def main(args: Array[String]) {
 *      //..
 *    }
 *  }
 *  }}}
 *
 *  @author  Matthias Zenger
 *  @version 1.0, 10/09/2003
 */
@deprecated("use App instead", "2.9.0")
trait Application {

  /** The time when the execution of this program started,
    * in milliseconds since 1 January 1970 UTC. */
  val executionStart: Long = currentTime

  /** The default main method.
   *
   *  @param args the arguments passed to the main method
   */
  def main(args: Array[String]) {
    if (util.Properties propIsSet "scala.time") {
      val total = currentTime - executionStart
      Console.println("[total " + total + "ms]")
    }
  }
}