@@ -371,59 +371,17 @@ val stubs = listOf(
371371
372372val stubsClassesDir = layout.buildDirectory.dir(" generated/teavm-stubs/classes" )
373373
374- // TeaVM's classlib jar ships `META-INF/teavm.properties` with the directive
375- // `includePackageHierarchy|java=false` — meaning every classpath entry whose class names start
376- // with `java.` is *excluded* by default (TeaVM expects to provide them itself, via the
377- // `org.teavm.classlib.java.*` → `java.*` renaming). Our stubs jar carries an additional
378- // `META-INF/teavm.properties` that *re-includes* the specific java.* / jakarta.* / javax.*
379- // sub-packages we ship stubs for, so the renamer doesn't drop them on the floor.
380- val teavmStubsIncludes = listOf (
381- // Mapping rules so my generated `org.teavm.classlib.<pkg>.T<Class>` stubs surface as the
382- // requested `<pkg>.<Class>` classes. teavm-classlib already ships these for `java.*`; the
383- // jakarta.* and javax.* lines below add equivalent prefixes for the packages it doesn't
384- // cover. Package-hierarchy rules cascade to sub-packages.
385- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.jakarta=T" ,
386- " mapPackageHierarchy|org.teavm.classlib.jakarta=jakarta" ,
387- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.javax=T" ,
388- " mapPackageHierarchy|org.teavm.classlib.javax=javax" ,
389- // org.w3c.* and org.xml.* — same shape, distinct package roots.
390- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.org.w3c=T" ,
391- " mapPackageHierarchy|org.teavm.classlib.org.w3c=org.w3c" ,
392- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.org.xml=T" ,
393- " mapPackageHierarchy|org.teavm.classlib.org.xml=org.xml" ,
394- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.org.glassfish=T" ,
395- " mapPackageHierarchy|org.teavm.classlib.org.glassfish=org.glassfish" ,
396- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.jakarta.xml=T" ,
397- " mapPackageHierarchy|org.teavm.classlib.jakarta.xml=jakarta.xml" ,
398- // com.beanit, com.google.gson, io.r2dbc — leaf libraries we excluded from the dep graph;
399- // these prefixes let the stubs surface where TeaVM expects to find the original classes.
400- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.com.beanit=T" ,
401- " mapPackageHierarchy|org.teavm.classlib.com.beanit=com.beanit" ,
402- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.com.google=T" ,
403- " mapPackageHierarchy|org.teavm.classlib.com.google=com.google" ,
404- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.io.r2dbc=T" ,
405- " mapPackageHierarchy|org.teavm.classlib.io.r2dbc=io.r2dbc" ,
406- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.org.jooq=T" ,
407- " mapPackageHierarchy|org.teavm.classlib.org.jooq=org.jooq" ,
408- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.org.reactivestreams=T" ,
409- " mapPackageHierarchy|org.teavm.classlib.org.reactivestreams=org.reactivestreams" ,
410- // SLF4J shim: org.teavm.classlib.org.slf4j.TLoggerFactory → org.slf4j.LoggerFactory.
411- // Replaces SLF4J's real LoggerFactory whose provider-discovery static init would
412- // otherwise abort the moment any rell-base `companion object: KLogging()` resolves.
413- " stripPrefixFromPackageHierarchyClasses|org.teavm.classlib.org.slf4j=T" ,
414- " mapPackageHierarchy|org.teavm.classlib.org.slf4j=org.slf4j" ,
415- // teavm-classlib excludes javax.xml from project-classpath lookups by default
416- // (`includePackageHierarchy|javax.xml=false`); the rename above re-enables it for the
417- // sub-tree we ship stubs for.
418- " includePackageHierarchy|javax.xml=true" ,
419- )
374+ // The `org.teavm.classlib.<pkg>.T<Class>` stubs below are surfaced as the requested
375+ // `<pkg>.<Class>` classes by RellPlaygroundSubstitutionPolicy (a SubstitutionPolicy SPI). Up to
376+ // 0.14 this remapping was driven by `mapPackageHierarchy` / `stripPrefixFromPackageHierarchyClasses`
377+ // directives in a `META-INF/teavm.properties` we shipped in this jar; 0.15.0-dev-3 deleted the
378+ // classpath property-renamer from teavm-core, so the rules now live in that policy class instead.
420379
421380val generateTeavmStubs by tasks.registering {
422381 description = " Emits empty stub bytecode for JDK packages TeaVM's classlib omits."
423382 group = LifecycleBasePlugin .BUILD_GROUP
424383
425384 inputs.property(" stubs" , stubs.joinToString { " ${it.name} |${it.isInterface} " })
426- inputs.property(" includes" , teavmStubsIncludes.joinToString(" \n " ))
427385 outputs.dir(stubsClassesDir)
428386
429387 doLast {
@@ -465,11 +423,6 @@ val generateTeavmStubs by tasks.registering {
465423 classFile.parentFile.mkdirs()
466424 classFile.writeBytes(cw.toByteArray())
467425 }
468-
469- // teavm.properties: re-includes the java.* / jakarta.* / javax.* sub-packages we ship.
470- val propsFile = outDir.resolve(" META-INF/teavm.properties" )
471- propsFile.parentFile.mkdirs()
472- propsFile.writeText(teavmStubsIncludes.joinToString(" \n " , postfix = " \n " ))
473426 }
474427}
475428
@@ -521,27 +474,26 @@ dependencies {
521474
522475 implementation(libs.rell.api.base)
523476
524- // teavm-jso brings the @JSExport annotation used to expose static Kotlin methods to JS.
525- // The annotation has no runtime semantics on JVM; TeaVM consumes it at compile time.
526477 compileOnly(libs.teavm.jso)
527-
528- // teavm-core: needed to compile the TeaVMPlugin / ClassHolderTransformer at
529- // com.chromia.rellplayground.teavm.*. Marked `compileOnly` because the plugin classes are
530- // loaded by TeaVM's own daemon (which already has teavm-core on its classpath) — shipping
531- // teavm-core itself into the compiled output would bloat the JS bundle with classes TeaVM
532- // never reaches at runtime.
533478 compileOnly(libs.teavm.core)
479+ compileOnly(libs.teavm.extension.spi)
534480
535- // TeaVM classpath. teavm(...) adds the entry to the configuration TeaVM compiles from
536- // (in addition to runtimeClasspath). jsoApis provides DOM + JSON types — we use a small
537- // subset (e.g. nothing yet) but it's required for the JS frontend's helpers.
538481 teavm(libs.teavm.jso.apis)
539482}
540483
541- // Tensor-probe parameters. Override on the CLI with -Prell.teavm.opt=BALANCED, -Prell.teavm.fast=true.
484+ // TeaVM codegen config. Overridable on the CLI (-Prell.teavm.opt=..., -Prell.teavm.fast=...,
485+ // -Prell.teavm.obf=...) but the defaults below are the only combination that produces a *working*
486+ // bridge on 0.15.0-dev-3:
487+ // - fastGlobalAnalysis = true is mandatory: precise analysis (fast=false) over-prunes
488+ // reflectively-reached init and emits JS that references eliminated symbols, so every
489+ // fast=false build crashes at runtime (C_LibBridge.instance uninitialized / ReferenceError).
490+ // - With fastGlobalAnalysis on, the optimizer's size/codegen passes are bypassed, so NONE /
491+ // BALANCED / AGGRESSIVE yield a byte-identical artifact — the opt level only changes build
492+ // time (AGGRESSIVE is just slower for the same output). BALANCED is the fastest viable build.
542493val probeOpt: OptimizationLevel = (project.findProperty(" rell.teavm.opt" ) as String? )
543- ?.let { OptimizationLevel .valueOf(it) } ? : OptimizationLevel .NONE
544- val probeFast: Boolean = (project.findProperty(" rell.teavm.fast" ) as String? )?.toBoolean() ? : false
494+ ?.let { OptimizationLevel .valueOf(it) } ? : OptimizationLevel .BALANCED
495+ val probeFast: Boolean = (project.findProperty(" rell.teavm.fast" ) as String? )?.toBoolean() ? : true
496+ val probeObfuscated: Boolean = (project.findProperty(" rell.teavm.obf" ) as String? )?.toBoolean() ? : true
545497
546498teavm {
547499 all {
@@ -578,7 +530,7 @@ teavm {
578530 optimization = probeOpt
579531 outOfProcess = true
580532 processMemory = 8192
581- obfuscated = true
533+ obfuscated = probeObfuscated
582534 sourceMap = false
583535 targetFileName = " rell-playground-bridge.wasm"
584536 }
0 commit comments