Using Gradle
There are two Gradle plugins: one for TeaVM library, another for TeaVM application. TeaVM library plugin only helps with adding JavaScript interop dependencies to your project and with testing your Java code in the browser. TeaVM application plugin adds tasks to build your application for various targets.
To add TeaVM support to your project, add following code to build.gradle
plugins {
id "org.teavm" version "0.13.1"
}
repositories {
mavenCentral()
}
for application project or
plugins {
id "org.teavm.library" version "0.13.1"
}
repositories {
mavenCentral()
}
for library project.
Application DSL
TeaVM application plugin adds DSL that allows to configure compilation for different targets.
teavm {
all {
// common configuration for all targets
}
js {
// configuration for JavaScript target
}
wasmGC {
// configuration for WebAssembly GC target
}
c {
// configuration for C (native) target
}
tests {
js {
// configuration for JavaScript tests
}
wasmGC {
// configuration for WebAssembly GC tests
}
}
}
You can also use shortened syntax, for example:
teavm.js {
// configuration for JS target only
}
Note that library plugin only supports tests section.
Common configuration properties
mainClass: String– application entry point (Java main class that containsmain(String[])method). This property is required.debugInformation: Boolean– instructs to produce debugging information. This is TeaVM proprietary format for JS and WebAssembly. Default value isfalse.fastGlobalAnalysis: Boolean– improve compilation time by reducing costs of global analysis, required for interprocedural optimizations like devirtualization, class initialization elimination, class cast elimination, etc. Can be used for debugging purposes. Default value isfalse.optimization: OptimizationLevel– which optimization level to use during compilation. Available values:NONE,BALANCED,AGGRESSIVE. Note thatAGGRESSIVElevel does not give significant performance growth for JS target, soBALANCEDis preferred, since with it compiler produces less code.NONEvalue produces code that is friendly to debuggers. Default value isBALANCEDfor JS andAGGRESSIVEfor other targets.properties: Map<String, String>– specifies properties that can fine-tune TeaVM libraries. These are usually library specific properties, please refer to library documentation. Some of the properties allow to fine-tune Java class library emulation.preservedClasses: List<String>– lists classes which should be preserved by TeaVM during compilation. TeaVM performs global analysis to determine which classes are necessary for execution and includes only these classes into final binary. However, in some cases you may need to manually preserve some classes. For example, if these classes export some methods for native target, not observable by compiler.outOfProcess: Boolean– tells whether TeaVM should be executed in a separate process.falseby default.processMemory: Int– in case TeaVM is executed in a separate process, how many memory, in megabytes, should be given to this process.outputDir: Directory– output directory. Default value is$buildDir/generated/teavm.
Additional configuration properties
obfuscated: Boolean(JS, WasmGC, C) – turns on obfuscation that produces less code and makes this code unreadable. Recommended for production. If you are developing open-source project and want others to see the code, you should share original Java/Kotlin/Scala code and publish source maps, instead of turning off obfuscation. For C target, removes metadata about call sites and source class/method names, which results in obfuscated stack traces. Default value istrue.strict: Boolean(JS, WasmGC) – add into generated code more checks (like null checks, array range checks, etc.). Most software should not depend on the code that catches NPE, IOOBE, etc. and does something beyond just reporting it. If it's the case, you should turn on strict mode, which affects negatively generated code size and performance. Default value isfalsefor JS andtruefor WasmGC.sourceMap: Boolean(JS, WasmGC) – produce source maps. Default value isfalse.entryPointName: String(JS) – name of JavaScript function that starts the main method. Note that it does not affect the name or the signature of a main method in Java sources (which is alwaysmain). Default value ismain.relativePathInOutputDir(JS, WasmGC) – directory, relative tooutputDir, where generated files will be written. Default value isjsfor JS backend andwasm-gcfor WebAssembly GC backend.targetFileName: String(JS, WasmGC) – name of target file. Default value is***.jsor***.wasmrespectively.addedToWebApp: Boolean(JS, WasmGC) – used in conjunction withwarplugin. Adds corresponding TeaVM task as a dependency to WAR tasks and includes TeaVM output into generated.warfile. Default value isfalse.maxTopLevelNames: Int(JS) – how many names to generate at top-level. All other declarations are generated as properties of some additional object. The reason to limit the number of top-level declarations is the bug in Chromium-based browsers that throw stack overflow error.sourceFilePolicy: SourceFilePolicy(JS, WasmGC) – declares how to produce paths to source files when source maps are generated. Possible values:DO_NOTHING– provide path to source files as is without any resolution. In this case the developer must ensure themselves that source files are served together with generated file.COPY– copies sources to the output directory.LINK_LOCAL_FILES– when possible, generatefile://URLs with paths in local file system.
moduleType: JSModuleType(JS) – which type of JavaScript module to use:COMMON_JS– CommonJS (compatible with node.js);UMD– UMD (automatically detect, at run time, AMD or CommonJS module system; behave as IIF otherwise);NONE– no module system, all code placed in immediately-invoked function (IIF);ES2015– ES2015 module.
minHeapSize: Int(C) – minimal (initial) heap size, in megabytes. Default value is1.maxHeapSize: Int(C) – maximal heap size, in megabytes. Default value is16.heapDump: Boolean(C) – include into generated virtual machine metadata that allows the VM to generate heap dump on irrecoverable crash. Default value isfalse.shortFileNames: Boolean(C) – generate shorter file names. Used to work around the buggy Microsoft C++ compiler. Default value isfalse.
WebAssembly GC-specific properties
copyRuntime: Boolean– whether to copy the Wasm GC runtime JavaScript file alongside the.wasmoutput. The runtime is required to load the module. Default value istrue.modularRuntime: Boolean– generate runtime as an ES6 module. Default value isfalse.disassembly: Boolean– generate a human-readable WAST disassembly in an HTML file, useful for debugging. Default value isfalse.debugInfoLocation: WasmDebugInfoLocation– where to store debug information:EMBEDDED– embed debug info as a custom section inside the.wasmfile;EXTERNAL– write a separate.teadbgfile alongside the.wasmfile (default).
debugInfoLevel: WasmDebugInfoLevel– how much debug information to generate:DEOBFUSCATION– only enough to deobfuscate stack traces (default);FULL– complete debug information.
minDirectBuffersSize: Int– minimum linear memory size in megabytes, used for NIO direct buffers and JS/Wasm data transfer. Default value is2.
Emscripten interop (WasmGC)
The WasmGC target supports linking native C/C++ code compiled with Emscripten. Configure it via the nested
emscripten {} block inside wasmGC {}:
teavm.wasmGC {
emscripten {
enabled = true
exportedFunctions.add("_myFunction")
compilerArgs.add("-O2")
}
}
See Emscripten integration guide for a step-by-step guide and Loader API for the JavaScript API to load the compiled module.
Including dependencies
TeaVM produces a number of additional libraries. To shorten access to these libraries, you can use the TeaVM DSL object instead of providing full addresses. These shortcuts are available in the TeaVM DSL object.
teavm.libs.jso– JSO library that defines primitives for interacting with native JavaScript.teavm.libs.jsoApis– library that, based on JSO primitives, declares stubs for interacting with commonly used browser APIs.teavm.libs.interop– library that defines primitives for interacting with external WebAssembly modules and with native libraries (in case of C target).teavm.libs.metaprogramming– library that simplifies compile-time code generation, that can be used instead of reflection.
Example:
dependencies {
implementation teavm.libs.jso
}
Properties
TeaVM plugin resolves its properties from three sources, in order of decreasing priority:
- JVM system properties — prefix the property name with
teavm., e.g.-Dteavm.emscripten-location=/path/to/emscripten. - TeaVM property files —
teavm.propertiesandteavm-local.propertiesin the project root, where definitions inteavm-local.propertiesoverride those inteavm.properties.teavm-local.propertiesshould be added to VCS ignore so each developer can supply their own values without affecting the shared repository state. - Gradle properties — prefix the property name with
teavm.in anygradle.propertiesfile, including the user-level~/.gradle/gradle.properties. This is useful for machine-wide settings that apply to all projects, such as the Emscripten SDK location.
Plugin also allows you to define configuration by redefining properties. Following list defines these properties:
js.obfuscatedjs.sourceMapjs.strictjs.addedToWebAppjs.optimizationjs.moduleTypejs.sourceFilePolicyjs.devServer.stackDeobfuscatedjs.devServer.indicatorjs.devServer.autoReloadjs.devServer.portjs.devServer.proxy.urljs.devServer.proxy.pathjs.devServer.memorywasm-gc.optimizationwasm-gc.addedToWebAppwasm-gc.strictwasm-gc.obfuscatedwasm-gc.copyRuntimewasm-gc.modularRuntimewasm-gc.disassemblywasm-gc.sourceMapwasm-gc.sourceFilePolicywasm-gc.debugInformationwasm-gc.debugInformation.locationwasm-gc.debugInformation.levelwasm-gc.minDirectBuffersSizewasm-gc.maxDirectBuffersSizewasm-gc.emscripten.compilerArgsemscripten-locationc.heapDumpc.shortFileNamesc.optimizationdebugInformationfastGlobalAnalysisoutOfProcessprocessMemory
You can also read values of properties via the TeaVM DSL object using following notation:
teavm.property('propertyName').
Tasks
TeaVM plugin adds a number of tasks that you can invoke directly or add to dependencies of a lifecycle task. Here is a summary:
JavaScript
generateJavaScript– compiles Java/Kotlin/Scala code to JavaScript.javaScriptDevServer– starts a long-running development server that caches compiler state and serves the compiled JS file over HTTP with hot-reload support.stopJavaScriptDevServer– stops the development server.
WebAssembly GC
generateWasmGC– compiles code to WebAssembly GC format.copyWasmGCRuntime– copies the runtime JavaScript file (and optionally the deobfuscator) next to the.wasmoutput. The runtime is required to load the module in a browser or Node.js.disasmWasmGC– generates a human-readable WAST disassembly as an HTML file (requiresdisassembly = true).emscriptenStubWasmGC– generates a C stub header (teavm-imports.c) that wires Java native method declarations to the Emscripten-compiled C/C++ code.emscriptenWasmGC– compiles the C/C++ sources fromsrc/teavm/emcc/withemccand produces the native.js+.wasmpair.buildWasmGC– convenience task that runsgenerateWasmGC,copyWasmGCRuntime,disasmWasmGC, and the Emscripten tasks in the correct order.
C / native
generateC– compiles code to C source files for further compilation with a native C/C++ compiler.
You may want to include tasks in dependencies of other lifecycle tasks, for example:
tasks.assemble.dependsOn(tasks.buildWasmGC)
Additional source set and configuration
In case you need to write a web application with TeaVM client code,
you may want to avoid presence of TeaVM-specific client libraries and class files in the war file.
For this purpose you can put your client code under the teavm source set, i.e.
in src/teavm/java (or src/teavm/kotlin, src/teavm/scala respectively)
instead of the usual src/main/java.
You can also put TeaVM-specific libraries into the teavm configuration instead of implementation,
for example:
dependencies {
teavm(teavm.libs.jsoApis)
}
C/C++ source files for Emscripten interop go in src/teavm/emcc/ (files with extensions
.c, .cpp, .C, .cc, .cxx, .c++).
JavaScript development server
In addition to normal builds, the development server can be used to improve developer experience. Development server is a separate process that keeps running between builds and serves files via HTTP. This allows the development server to cache compiler structures between rebuilds and thus speed up subsequent builds. Also, development server injects some additional metadata that allow deobfuscating stack traces on-the-fly. Finally, development server serves source maps together with source files, which can improve the debugging experience.
To start development server, configure it using following DSL:
teavm {
js {
devServer {
port = port_number
// .. other values
}
}
}
or shorter
teavm.js.devServer {
// configuration properties here
}
and run javaScriptDevServer. The generated file will be served from
http://localhost:***/***/***.js, where placeholders correspond to
configuration properties. Subsequent runs of the same task will just instruct the server to re-build the
JavaScript file.
As you make changes to project, run javaScriptDevServer again. This won't restart the server.
Instead, it will inform the server that the .class files were changed and the server needs to pick them
and re-build the JavaScript file.
To stop the server process, run stopJavaScriptDevServer task.
Available configuration properties:
port– port number the HTTP server listens on.stackDeobfuscated– whether all JS stacks should be deobfuscated and proper Java stack traces generated.indicator– injects a small indicator in the lower-left corner of the page to display compilation progress right in the web page.autoReload– indicates whether the page should be reloaded as soon as compilation completes.processMemory– amount of memory, in megabytes, to allocate for the server process.proxyUrl– when specified, development server will not only serve generated JavaScript, but also proxy all incoming requests to the given URL.proxyPath– used in conjunction withproxyUrl. When specified, only requests starting with the specified path will be proxied.