5050import javax .xml .transform .stream .StreamResult ;
5151import javax .xml .transform .stream .StreamSource ;
5252
53+ import org .jetbrains .annotations .Nullable ;
5354import org .w3c .dom .Node ;
5455import org .xml .sax .SAXException ;
5556
@@ -65,30 +66,34 @@ public record MinecraftMaven(
6566 boolean globalAuxiliaryVariants ,
6667 boolean disableGradle ,
6768 boolean stubJars ,
68- Set <String > mcpConfigVersions
69+ Set <String > mcpConfigVersions ,
70+ @ Nullable File accessTransformer
6971) {
7072 // Only 1.14.4+ has official mappings, we can support more when we add more mappings
7173 private static final MinecraftVersion MIN_OFFICIAL_MAPPINGS = MinecraftVersion .from ("1.14.4" );
7274 private static final ComparableVersion MIN_SUPPORTED_FORGE = new ComparableVersion ("1.14.4" );
7375
7476 public MinecraftMaven (File output , boolean dependenciesOnly , File cacheRoot , File jdkCacheRoot , Mappings mappings ,
75- Map <String , String > foreignRepositories , boolean globalAuxiliaryVariants , boolean disableGradle , boolean stubJars ) {
76- this (output , dependenciesOnly , new Cache (cacheRoot , jdkCacheRoot , foreignRepositories ), mappings , foreignRepositories , globalAuxiliaryVariants , disableGradle , stubJars , new HashSet <>());
77+ Map <String , String > foreignRepositories , boolean globalAuxiliaryVariants , boolean disableGradle , boolean stubJars ,
78+ @ Nullable File accessTransformer ) {
79+ this (output , dependenciesOnly , new Cache (cacheRoot , jdkCacheRoot , foreignRepositories ), mappings , foreignRepositories , globalAuxiliaryVariants , disableGradle , stubJars , new HashSet <>(), accessTransformer );
7780 }
7881
7982 public MinecraftMaven {
80- LOGGER .info (" Output: " + output .getAbsolutePath ());
81- LOGGER .info (" Dependencies Only: " + dependenciesOnly );
82- LOGGER .info (" Cache: " + cache .root ().getAbsolutePath ());
83- LOGGER .info (" JDK Cache: " + cache .jdks ().root ().getAbsolutePath ());
84- LOGGER .info (" Offline: " + Mavenizer .isOffline ());
85- LOGGER .info (" Cache Only: " + Mavenizer .isCacheOnly ());
86- LOGGER .info (" Mappings: " + mappings );
83+ LOGGER .info (" Output: " + output .getAbsolutePath ());
84+ LOGGER .info (" Dependencies Only: " + dependenciesOnly );
85+ LOGGER .info (" Cache: " + cache .root ().getAbsolutePath ());
86+ LOGGER .info (" JDK Cache: " + cache .jdks ().root ().getAbsolutePath ());
87+ LOGGER .info (" Offline: " + Mavenizer .isOffline ());
88+ LOGGER .info (" Cache Only: " + Mavenizer .isCacheOnly ());
89+ LOGGER .info (" Mappings: " + mappings );
8790 if (!foreignRepositories .isEmpty ())
88- LOGGER .info (" Foreign Repos: [" + String .join (", " , foreignRepositories .values ()) + ']' );
89- LOGGER .info (" GradleVariantHack: " + globalAuxiliaryVariants );
90- LOGGER .info (" Disable Gradle: " + disableGradle );
91- LOGGER .info (" Stub Jars: " + stubJars );
91+ LOGGER .info (" Foreign Repos: [" + String .join (", " , foreignRepositories .values ()) + ']' );
92+ LOGGER .info (" GradleVariantHack: " + globalAuxiliaryVariants );
93+ LOGGER .info (" Disable Gradle: " + disableGradle );
94+ LOGGER .info (" Stub Jars: " + stubJars );
95+ if (accessTransformer != null )
96+ LOGGER .info (" Access Transformer: " + accessTransformer .getAbsolutePath ());
9297 LOGGER .info ();
9398 }
9499
@@ -301,9 +306,18 @@ protected void finalize(Artifact module, Mappings mappings, List<Repo.PendingArt
301306 }
302307
303308 private void updateFile (File target , File source , Artifact artifact ) {
304- if (stubJars && "jar" .equals (artifact .getExtension ())) {
305- writeStub (target , source , artifact );
306- return ;
309+ var isJar = "jar" .equals (artifact .getExtension ());
310+ if (isJar ) {
311+ if (stubJars ) {
312+ writeStub (target , source , artifact );
313+ return ;
314+ }
315+
316+ // Only transform main artifacts
317+ if (accessTransformer != null && artifact .getClassifier () == null ) {
318+ writeAccessTransformed (target , source , artifact );
319+ return ;
320+ }
307321 }
308322
309323 var cache = HashStore .fromFile (target )
@@ -365,6 +379,42 @@ private void writeStub(File target, File source, Artifact artifact) {
365379 }
366380 }
367381
382+ private void writeAccessTransformed (File target , File source , Artifact artifact ) {
383+ var tool = this .cache .maven ().download (Constants .ACCESS_TRANSFORMER );
384+ var cache = HashStore .fromFile (target )
385+ .add ("tool" , tool )
386+ .add ("at" , accessTransformer )
387+ .add ("source" , source );
388+
389+ if (target .exists () && cache .isSame ())
390+ return ;
391+
392+ File jdk ;
393+ try {
394+ jdk = this .cache .jdks ().get (Constants .ACCESS_TRANSFORMER_JAVA_VERSION );
395+ } catch (Exception e ) {
396+ throw new IllegalStateException ("Failed to find JDK for version " + Constants .ACCESS_TRANSFORMER_JAVA_VERSION , e );
397+ }
398+
399+ var log = new File (source .getAbsolutePath () + ".accesstransformer.log" );
400+ var ret = ProcessUtils .runJar (jdk , source .getParentFile (), log , tool , Collections .emptyList (),
401+ List .of (
402+ "--inJar" , source .getAbsolutePath (),
403+ "--outJar" , target .getAbsolutePath (),
404+ "--atfile" , accessTransformer .getAbsolutePath ()
405+ )
406+ );
407+ if (ret .exitCode != 0 )
408+ throw new IllegalStateException ("Failed to Access Transform jar file (exit code " + ret .exitCode + "), See log: " + log .getAbsolutePath ());
409+
410+ try {
411+ cache .save ();
412+ HashUtils .updateHash (target );
413+ } catch (Throwable t ) {
414+ throw new RuntimeException ("Failed to generate artifact: %s" .formatted (artifact ), t );
415+ }
416+ }
417+
368418 private void updateVariants (Artifact artifact ) {
369419 var root = new File (this .output , artifact .getFolder ());
370420 var inputs = new ArrayList <File >();
0 commit comments