Skip to content
This repository has been archived by the owner on Jan 5, 2021. It is now read-only.

PSA Forward Compatibility Features in Mixin

Sotr edited this page May 17, 2018 · 1 revision

Mixin includes a number of features and design considerations which aim to not only provide backward compatibility but address forward compatibility concerns as well. Since the purpose of these might not be apparent I will endeavour to outline them here. However the emphasis of this PSA is on the usage of the minVersion key provided in mixin configs, and its applicability to the stability of your application.

1. Mixin Config property minVersion

The minVersion property is the most important piece of forward-compatibility infrastructure available to you, and it should not be overlooked. A safe approach to the use of the minVersion property is to always set it to the version of Mixin you build against. Maintaining the value manually provides more flexibility however, if you are not utilising features in the version you are building against.

So what does the minVersion key do?

Let's assume that two libraries, ModA and ModB, both of which use Mixin, are loaded by an application environment. ModA shades version 0.6 of Mixin, and ModB includes version 0.7. Both libraries specify the correct minVersion in their configurations.

If ModA happens to be loaded before ModB, the version of Mixin loaded will be 0.6. When ModB attempts to add its mixin configs, the application can fail-fast because it detects that the version of Mixin loaded is too old to support the features required by ModB's mixins.

However, if ModB forgets to update the minVersion property in the config, the application will instead fail in a non-deterministic manner later on. Depending on the situation, the later error may seem crptic and might not even imply that the issue is related to the outdated Mixin version.

Use of minVersion in the config ensures this fail-fast behaviour.

1.1 General contract of Mixin wrt. backward compatibility

Since the general contract of the Mixin library is that Mixin will always guarantee mixins written for an older version will either continue to work or will fail-fast in a deterministic way, the presence of a later version at runtime does not present a problem.

Conversely, the presence of an older version than required can have unpredictable results, which can be readily and easily remedied by including the minVersion property.

1.2 Writing minVersion using your build script

The minVersion property itself is parsed as a string into a semver-compatible version number, and ignored in all other cases. This means it is perfectly fine to use a replacement token in the minVersion property (eg. ${version}) and replace the token at compile-time in your build script. The "invalid" value will simply be ignored in your development workspace, and the correct value will be present in your compiled artefact.

2. Mixin config property compatibilityLevel

As new versions of Java are released, new features are added to Mixin to support those new language features. The compatibilityLevel property can be used to elevate Mixin's operating level to the required level for the feature set you wish to use. The default level is JAVA_6.

At present, each elevation is able to support all features of the language level below, and it is possible to anticipate that this situation will prevail.

Elevation of the compatibility level serves two purposes:

  • Firstly, if the current runtime does not support the requested feature set (eg. attempting to elevate to JAVA_9 whilst running Java 8) then the operation can fail fast.
  • Secondly, if a future version of Java prevents safe inter-operation with an older language version (for example if Java 12 comes along and necessitates a breaking change from Java 6 which makes Java 6 mixins unsupportable on that platform) then that sitation can also fail fast and/or partition the mixin sets into current generation and legacy mode.

This means that like the minVersion property, maintaining the compatibilityLevel property is important for the long-term stability of your library. compatibilityLevel should always be set to the highest level required by your mixins.