Skip to content

Versioned injection - #35

Draft
OrderedSet86 wants to merge 2 commits into
devfrom
versioned-injection
Draft

Versioned injection#35
OrderedSet86 wants to merge 2 commits into
devfrom
versioned-injection

Conversation

@OrderedSet86

@OrderedSet86 OrderedSet86 commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

The LLM didn't seem to the existing @versioned much, so it applied these fixes.

You're welcome to override or throw away these changes (I did not test them extensively), but I thought I should post them in case it is useful


@Versioned has never injected anything. Two independent faults, either alone enough, plus a third that could stop the game loading.

Fixed

  • The target class never resolved. The fallback was
    Class.forName(inner.getSimpleName()), which always throws; the mirror was
    skipped before any field was reached, so the existing warning never fired.
    @Versioned.Class now requires the class named in full.
  • The mirrors were compiled away. A static final int with a literal
    initializer is a JLS 4.12.4 constant variable, folded into every use site, so
    the write landed where nothing reads. Mirrors are now non-final: reads of
    AE2Provider's TileInscriber mirror went from 0 getstatic to 4, and its
    three ConstantValue attributes are gone.
  • An absent mod could take preInit down. injectAll loaded every annotated
    provider regardless, catching only ReflectiveOperationException - a provider
    names its mod's types throughout, so the load raises NoClassDefFoundError.
    The mod id is now read from the ASM table and checked before anything loads.
  • Private constants were unreadable, for want of a setAccessible. AE2's
    mirrors are public so it never showed; most mods keep constants private.
  • Unsafe is gone, with its seven [removal] warnings. It was only needed
    to write a static final, which mirrors no longer are.

Added

  • @Versioned.Constant is @Repeatable, so one constant can follow a field the
    dependency renamed: one annotation per name, newest first, first that resolves
    wins. Drift is reported against the earliest version any name was expected under.

Tests

  • VersionedInjectionTest - the mechanism, against a stand-in dependency declared
    in the test, so no mod is needed and no assertion drifts into claiming something
    about that mod's balance.
  • VersionedAsmSweepTest - the FML sweep, including that an absent mod's provider
    is never classloaded.
  • VersionedMirrorShapeTest - fails if a mirror declares a final field. A source
    check, because reflection cannot tell an injected final from a folded one.

Not in scope

Reading a field off every constant of a dependency enum, and reading enum names as
a list. Both are wanted; neither has a caller on dev.

For review

  • modPresent and installed look like one predicate written twice. They are
    not: with no Forge to ask, one must answer "proceed" and the other "do not warn".
  • @Versioned.Class(clazz = ...) stays a trap for an optional mod, since reading
    a Class-valued element whose class is absent throws TypeNotPresentException.
    The sweep contains that now and the javadoc points at value(). Say if the
    element should go.
  • On AE2 rv3-beta-1017, TileMolecularAssembler.MAX_PROCESSING_TIME logs one
    warning per launch - AE2 has no such field there. Worth leaving: on the same
    class, ACCELERATION_TAX is absent in 987 and 997 and present in 1017, so a
    mirror missing from the pinned version is the case this annotation exists for.

@OrderedSet86
OrderedSet86 requested a review from sbancuz August 29, 2026 19:38
@sbancuz

sbancuz commented Aug 29, 2026

Copy link
Copy Markdown
Owner

I remember testing it before this changed and it worked, what actual bug are you trying to fix? Do they not change values as expected?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants