package app
- Alphabetic
- Public
- Protected
Type Members
- trait App extends ClosableOnce with CloseOnceAwaitably with Lifecycle
A composable application trait that includes flag parsing as well as basic application lifecycle (pre- and post- main).
A composable application trait that includes flag parsing as well as basic application lifecycle (pre- and post- main). Flag parsing is done via com.twitter.app.Flags, an instance of which is defined in the member
flag
. Applications should be constructed with modularity in mind, and common functionality should be extracted into mixins.Flags should only be constructed in the constructor, and should only be read in the premain or later, after they have been parsed.
import com.twitter.app.App object MyApp extends App { val n = flag("n", 100, "Number of items to process") def main(): Unit = { for (i <- 0 until n()) process(i) } }
Note that a missing
main
is OK: mixins may provide behavior that does not require defining a custommain
method. - final class CloseException extends Exception with NoStackTrace
An exception that represents collected errors which occurred on close of the app.
An exception that represents collected errors which occurred on close of the app.
- Note
When execution of the
,App#nonExitingMain
throws a CloseException, the app will not attempt to callApp#close()
again in theApp#exitOnError(t: Throwable)
function since this Exception is assumed be a result of already callingApp#close()
.Collected exceptions which occurred during closing are added as "suppressed" exceptions.
- See also
https://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html#getSuppressed()
- class Flag[T] extends AnyRef
A single command-line flag, instantiated by a com.twitter.app.Flags instance.
A single command-line flag, instantiated by a com.twitter.app.Flags instance.
The current value can be extracted via apply, get, and getWithDefault. Local-scoped modifications of their values, which can be useful for tests, can be done by calls to let and letClear.
Using a
String
-typed Flag,myFlag
, which is unset and has a default value of "DEFAULT" as an example:myFlag.isDefined // => false myFlag.get // => None myFlag.getWithDefault // => Some("DEFAULT") myFlag() // => "DEFAULT" myFlag.let("a value") { myFlag.isDefined // => true myFlag.get // => Some("a value") myFlag.getWithDefault // => Some("a value") myFlag() // => "a value" myFlag.letClear { myFlag.isDefined // => false myFlag.get // => None myFlag.getWithDefault // => Some("DEFAULT") myFlag() // => "DEFAULT" } }
- See also
com.twitter.app.Flags for information on how flags can be set by the command line.
- case class FlagParseException(message: String, cause: Throwable = null) extends Exception with Product with Serializable
Exception thrown upon flag-parsing failure.
Exception thrown upon flag-parsing failure. Should typically lead to process death, since continued execution would run the risk of unexpected behavior on account of incorrectly-interpreted or malformed flag values.
- message
A string name of the flag for which parsing failed.
- cause
The underlying
java.lang.Throwable
that caused this exception.
- class FlagUndefinedException extends Exception
- case class FlagUsageError(usage: String) extends Exception with Product with Serializable
- class FlagValueRequiredException extends Exception
- abstract class Flaggable[T] extends AnyRef
A type class providing evidence for parsing type
T
as a flag value.A type class providing evidence for parsing type
T
as a flag value.Any class that is to be provided as a flaggable value must have an accompanying implicit
Flaggable
(contained within a companion object of the class in question) for converting a string to an object of that type. For instance, to make a hypothetical type calledFoo
flaggable:class Foo { ... } object Foo { implicit val flagOfFoo = new Flaggable[Foo] { def parse(v: String): Foo = { ... } } }
For simple implicit definitions based on existing
String => T
functions, use theFlaggable.mandatory
function:object Foo { def parse(v: String): Foo = { ... } implicit val ofFoo = Flaggable.mandatory(Foo.parse(_)) }
[1] https://en.wikipedia.org/wiki/Type_class
- final class Flags extends AnyRef
A simple flags implementation.
A simple flags implementation. We support only two formats:
for flags with optional values (e.g. booleans): -flag, -flag=value for flags with required values: -flag[= ]value
That's it. These can be parsed without ambiguity.
There is no support for mandatory arguments: That is not what flags are for.
Flags.apply
adds a new flag to the flag set, so it is idiomatic to assign instances ofFlags
to a singularflag
val:val flag = new Flags("myapp") val i = flag("i", 123, "iteration count")
Global flags, detached from a particular
Flags
instance but accessible to all, are defined by com.twitter.app.GlobalFlag. - abstract class GlobalFlag[T] extends Flag[T]
Subclasses of GlobalFlag (that are defined in libraries) are "global" in the sense that they are accessible by any application that depends on that library.
Subclasses of GlobalFlag (that are defined in libraries) are "global" in the sense that they are accessible by any application that depends on that library. Regardless of where in a library a GlobalFlag is defined, a value for it can be passed as a command-line flag by any binary that includes the library. The set of defined GlobalFlags can be enumerated (via
GlobalFlag.getAll)
by the application.A GlobalFlag must be declared as an
object
(see below for Java):import com.twitter.app.GlobalFlag object myFlag extends GlobalFlag[String]("default value", "this is my global flag")
All such global flag declarations in a given classpath are visible to and used by com.twitter.app.App.
A flag's name (as set on the command line) is its fully-qualified classname. For example, the flag
package com.twitter.server import com.twitter.app.GlobalFlag object port extends GlobalFlag[Int](8080, "the TCP port to which we bind")
is settable by the command-line flag
-com.twitter.server.port=8080
.Global flags may also be set by Java system properties with keys named in the same way. However, values supplied by flags override those supplied by system properties.
- Annotations
- @GlobalFlagVisible()
- trait GlobalFlagVisible extends Annotation
- Annotations
- @Retention() @Inherited()
- abstract class JavaGlobalFlag[T] extends GlobalFlag[T]
In order to declare a new GlobalFlag in Java, it can be done with a bit of ceremony by following a few steps:
In order to declare a new GlobalFlag in Java, it can be done with a bit of ceremony by following a few steps:
- the flag's class name must end with "$", e.g.
javaGlobalWithDefault$
. This is done to mimic the behavior of Scala's singletonobject
. - the class must have a method,
public static Flag<?> globalFlagInstance()
, that returns the singleton instance of the Flag. - the class should have a
static final
field holding the singleton instance of the flag. - the class should extend
JavaGlobalFlag
. - to avoid extraneous creation of instances, thus forcing users to only
access the singleton, the constructor should be
private
and the class should bepublic final
.
An example of a GlobalFlag declared in Java:
import com.twitter.app.Flag; import com.twitter.app.Flaggable; import com.twitter.app.JavaGlobalFlag; public final class exampleJavaGlobalFlag$ extends JavaGlobalFlag<String> { private exampleJavaGlobalFlag() { super("The default value", "The help string", Flaggable.ofString()); } public static final Flag<String> Flag = new exampleJavaGlobalFlag(); public static Flag<?> globalFlagInstance() { return Flag; } }
- the flag's class name must end with "$", e.g.
Value Members
- object App
- object Flag
- object Flaggable
Default
Flaggable
implementations. - object Flags
- object GlobalFlag
- object LoadService
Load classes in the manner of
java.util.ServiceLoader
.Load classes in the manner of
java.util.ServiceLoader
. It is more resilient to varying Java packaging configurations than ServiceLoader.For further control, see App.loadServiceBindings and the
loadServiceDenied
flag.