@@ -68,7 +68,7 @@ public static class Options {
6868 public static final RuntimeOptionKey <String > RecordMetadata = new RuntimeOptionKey <>("" );
6969 }
7070
71- private ConfigurationSet config ;
71+ private volatile ConfigurationSet config ;
7272
7373 private Path recordMetadataPath ;
7474
@@ -77,11 +77,20 @@ public static MetadataTracer singleton() {
7777 return ImageSingletons .lookup (MetadataTracer .class );
7878 }
7979
80+ /**
81+ * Returns whether tracing is enabled at run time (using {@code -XX:RecordMetadata=path}).
82+ */
8083 public boolean enabled () {
8184 VMError .guarantee (Options .MetadataTracingSupport .getValue ());
82- return config != null ;
85+ return recordMetadataPath != null ;
8386 }
8487
88+ /**
89+ * Marks the given type as reachable from reflection.
90+ *
91+ * @return the corresponding {@link ConfigurationType} or {@code null} if tracing is not active
92+ * (e.g., during shutdown).
93+ */
8594 public ConfigurationType traceReflectionType (String className ) {
8695 return traceReflectionTypeImpl (new NamedConfigurationTypeDescriptor (className ));
8796 }
@@ -95,29 +104,59 @@ public void traceProxyType(List<String> interfaceNames) {
95104
96105 private ConfigurationType traceReflectionTypeImpl (ConfigurationTypeDescriptor typeDescriptor ) {
97106 assert enabled ();
98- return config .getReflectionConfiguration ().getOrCreateType (UnresolvedConfigurationCondition .alwaysTrue (), new NamedConfigurationTypeDescriptor (className ));
107+ ConfigurationSet configurationSet = config ;
108+ if (configurationSet != null ) {
109+ return configurationSet .getReflectionConfiguration ().getOrCreateType (UnresolvedConfigurationCondition .alwaysTrue (), typeDescriptor );
110+ }
111+ return null ;
99112 }
100113
114+ /**
115+ * Marks the given type as reachable from JNI.
116+ *
117+ * @return the corresponding {@link ConfigurationType} or {@code null} if tracing is not active
118+ * (e.g., during shutdown).
119+ */
101120 public ConfigurationType traceJNIType (String className ) {
102121 assert enabled ();
103122 ConfigurationType result = traceReflectionType (className );
104- result .setJniAccessible ();
123+ if (result != null ) {
124+ result .setJniAccessible ();
125+ }
105126 return result ;
106127 }
107128
129+ /**
130+ * Marks the given resource within the given (optional) module as reachable.
131+ */
108132 public void traceResource (String resourceName , String moduleName ) {
109133 assert enabled ();
110- config .getResourceConfiguration ().addGlobPattern (UnresolvedConfigurationCondition .alwaysTrue (), resourceName , moduleName );
134+ ConfigurationSet configurationSet = config ;
135+ if (configurationSet != null ) {
136+ configurationSet .getResourceConfiguration ().addGlobPattern (UnresolvedConfigurationCondition .alwaysTrue (), resourceName , moduleName );
137+ }
111138 }
112139
140+ /**
141+ * Marks the given resource bundle within the given locale as reachable.
142+ */
113143 public void traceResourceBundle (String baseName ) {
114144 assert enabled ();
115- config .getResourceConfiguration ().addBundle (UnresolvedConfigurationCondition .alwaysTrue (), baseName , List .of ());
145+ ConfigurationSet configurationSet = config ;
146+ if (configurationSet != null ) {
147+ configurationSet .getResourceConfiguration ().addBundle (UnresolvedConfigurationCondition .alwaysTrue (), baseName , List .of ());
148+ }
116149 }
117150
151+ /**
152+ * Marks the given type as serializable.
153+ */
118154 public void traceSerializationType (String className ) {
119155 assert enabled ();
120- traceReflectionType (className ).setSerializable ();
156+ ConfigurationType result = traceReflectionType (className );
157+ if (result != null ) {
158+ result .setSerializable ();
159+ }
121160 }
122161
123162 private static void initialize () {
@@ -141,6 +180,7 @@ private static void shutdown() {
141180 assert Options .MetadataTracingSupport .getValue ();
142181 MetadataTracer singleton = MetadataTracer .singleton ();
143182 ConfigurationSet config = singleton .config ;
183+ singleton .config = null ; // clear config so that shutdown events are not traced.
144184 if (config != null ) {
145185 try {
146186 config .writeConfiguration (configFile -> singleton .recordMetadataPath .resolve (configFile .getFileName ()));
0 commit comments