Skip to content

Commit 8b67e3f

Browse files
committed
[GR-41614] Move resource registration to beforeAnalysis phase
PullRequest: graal/14560
2 parents 9ce1672 + b552181 commit 8b67e3f

File tree

22 files changed

+572
-257
lines changed

22 files changed

+572
-257
lines changed

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/hosted/RuntimeResourceAccess.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -40,17 +40,16 @@
4040
*/
4141
package org.graalvm.nativeimage.hosted;
4242

43-
import java.util.Arrays;
44-
import java.util.Locale;
45-
import java.util.Objects;
46-
import java.util.regex.Pattern;
47-
4843
import org.graalvm.nativeimage.ImageSingletons;
4944
import org.graalvm.nativeimage.Platform;
5045
import org.graalvm.nativeimage.Platforms;
5146
import org.graalvm.nativeimage.impl.ConfigurationCondition;
5247
import org.graalvm.nativeimage.impl.RuntimeResourceSupport;
5348

49+
import java.util.Arrays;
50+
import java.util.Locale;
51+
import java.util.Objects;
52+
5453
/**
5554
* This class can be used to register Java resources and ResourceBundles that should be accessible
5655
* at run time.
@@ -69,8 +68,7 @@ public final class RuntimeResourceAccess {
6968
public static void addResource(Module module, String resourcePath) {
7069
Objects.requireNonNull(module);
7170
Objects.requireNonNull(resourcePath);
72-
ImageSingletons.lookup(RuntimeResourceSupport.class).addResources(ConfigurationCondition.alwaysTrue(),
73-
withModuleName(module, Pattern.quote(resourcePath)));
71+
ImageSingletons.lookup(RuntimeResourceSupport.class).addResource(module, resourcePath);
7472
}
7573

7674
/**

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/ConfigurationCondition.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -50,6 +50,10 @@ public static ConfigurationCondition alwaysTrue() {
5050
return OBJECT_REACHABLE;
5151
}
5252

53+
public static boolean isAlwaysTrue(ConfigurationCondition condition) {
54+
return ConfigurationCondition.alwaysTrue().equals(condition);
55+
}
56+
5357
public static ConfigurationCondition create(String typeReachability) {
5458
Objects.requireNonNull(typeReachability);
5559
if (OBJECT_REACHABLE.typeName.equals(typeReachability)) {

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeResourceSupport.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -46,6 +46,8 @@
4646
public interface RuntimeResourceSupport {
4747
void addResources(ConfigurationCondition condition, String pattern);
4848

49+
void addResource(Module module, String resourcePath);
50+
4951
void injectResource(Module module, String resourcePath, byte[] resourceContent);
5052

5153
void ignoreResources(ConfigurationCondition condition, String pattern);

substratevm/mx.substratevm/mx_substratevm.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import tempfile
2929
from glob import glob
3030
from contextlib import contextmanager
31+
from distutils.dir_util import mkpath # pylint: disable=no-name-in-module
3132
from os.path import join, exists, dirname
3233
import pipes
3334
from argparse import ArgumentParser
@@ -475,9 +476,26 @@ def native_unittests_task(extra_build_args=None):
475476
# GR-24075
476477
mx_unittest.add_global_ignore_glob('com.oracle.svm.test.ProcessPropertiesTest')
477478

479+
# add resources that are not in jar but in the separate directory
480+
cp_entry_name = join(svmbuild_dir(), 'cpEntryDir')
481+
resources_from_dir = join(cp_entry_name, 'resourcesFromDir')
482+
simple_dir = join(cp_entry_name, 'simpleDir')
483+
484+
mkpath(cp_entry_name)
485+
mkpath(resources_from_dir)
486+
mkpath(simple_dir)
487+
488+
for i in range(4):
489+
with open(join(cp_entry_name, "resourcesFromDir", f'cond-resource{i}.txt'), 'w') as out:
490+
out.write(f"Conditional file{i}" + '\n')
491+
492+
with open(join(cp_entry_name, "simpleDir", f'simple-resource{i}.txt'), 'w') as out:
493+
out.write(f"Simple file{i}" + '\n')
494+
478495
additional_build_args = svm_experimental_options([
479496
'-H:AdditionalSecurityProviders=com.oracle.svm.test.SecurityServiceTest$NoOpProvider',
480497
'-H:AdditionalSecurityServiceTypes=com.oracle.svm.test.SecurityServiceTest$JCACompliantNoOpService',
498+
'-cp', cp_entry_name
481499
])
482500
if extra_build_args is not None:
483501
additional_build_args += extra_build_args

substratevm/src/com.oracle.svm.configure.test/src/com/oracle/svm/configure/test/config/ResourceConfigurationTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@
3838
import org.junit.Test;
3939

4040
import com.oracle.svm.configure.config.ResourceConfiguration;
41-
import com.oracle.svm.core.util.json.JsonWriter;
4241
import com.oracle.svm.core.configure.ResourceConfigurationParser;
4342
import com.oracle.svm.core.configure.ResourcesRegistry;
43+
import com.oracle.svm.core.util.VMError;
44+
import com.oracle.svm.core.util.json.JsonWriter;
4445

4546
public class ResourceConfigurationTest {
4647

@@ -93,6 +94,11 @@ public void addResources(ConfigurationCondition condition, String pattern) {
9394
addedResources.add(pattern);
9495
}
9596

97+
@Override
98+
public void addResource(Module module, String resourcePath) {
99+
throw VMError.shouldNotReachHere("Unused function.");
100+
}
101+
96102
@Override
97103
public void injectResource(Module module, String resourcePath, byte[] resourceContent) {
98104
}

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ResourceConfiguration.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@
3838
import org.graalvm.nativeimage.impl.ConfigurationCondition;
3939

4040
import com.oracle.svm.configure.ConfigurationBase;
41-
import com.oracle.svm.core.util.json.JsonPrinter;
42-
import com.oracle.svm.core.util.json.JsonWriter;
4341
import com.oracle.svm.core.configure.ConditionalElement;
4442
import com.oracle.svm.core.configure.ConfigurationParser;
4543
import com.oracle.svm.core.configure.ResourceConfigurationParser;
4644
import com.oracle.svm.core.configure.ResourcesRegistry;
4745
import com.oracle.svm.core.util.VMError;
46+
import com.oracle.svm.core.util.json.JsonPrinter;
47+
import com.oracle.svm.core.util.json.JsonWriter;
4848

4949
public final class ResourceConfiguration extends ConfigurationBase<ResourceConfiguration, ResourceConfiguration.Predicate> {
5050

@@ -63,6 +63,11 @@ public void addResources(ConfigurationCondition condition, String pattern) {
6363
configuration.addResourcePattern(condition, pattern);
6464
}
6565

66+
@Override
67+
public void addResource(Module module, String resourcePath) {
68+
throw VMError.shouldNotReachHere("Unused function.");
69+
}
70+
6671
@Override
6772
public void injectResource(Module module, String resourcePath, byte[] resourceContent) {
6873
VMError.shouldNotReachHere("Resource injection is only supported via Feature implementation");

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/ClassLoaderSupport.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,16 @@
2525
package com.oracle.svm.core;
2626

2727
import java.io.IOException;
28-
import java.io.InputStream;
2928
import java.net.URI;
3029
import java.util.List;
3130
import java.util.Locale;
31+
import java.util.Map;
3232
import java.util.ResourceBundle;
33+
import java.util.Set;
3334

3435
import org.graalvm.nativeimage.Platform;
3536
import org.graalvm.nativeimage.Platforms;
37+
import org.graalvm.nativeimage.impl.ConfigurationCondition;
3638

3739
@Platforms(Platform.HOSTED_ONLY.class)
3840
public abstract class ClassLoaderSupport {
@@ -51,12 +53,11 @@ public boolean isNativeImageClassLoader(ClassLoader classLoader) {
5153
protected abstract boolean isNativeImageClassLoaderImpl(ClassLoader classLoader);
5254

5355
public interface ResourceCollector {
56+
List<ConfigurationCondition> isIncluded(Module module, String resourceName, URI resourceURI);
5457

55-
boolean isIncluded(Module module, String resourceName, URI resourceURI);
58+
void addResource(Module module, String resourceName);
5659

57-
void addResource(Module module, String resourceName, InputStream resourceStream, boolean fromJar);
58-
59-
void addDirectoryResource(Module module, String dir, String content, boolean fromJar);
60+
void addResourceConditionally(Module module, String resourceName, ConfigurationCondition condition);
6061

6162
void registerNegativeQuery(Module module, String resourceName);
6263

@@ -66,4 +67,6 @@ public interface ResourceCollector {
6667
public abstract void collectResources(ResourceCollector resourceCollector);
6768

6869
public abstract List<ResourceBundle> getResourceBundle(String bundleName, Locale locale);
70+
71+
public abstract Map<String, Set<Module>> getPackageToModules();
6972
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Resources.java

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ private void updateTimeStamp() {
166166
}
167167

168168
@Platforms(Platform.HOSTED_ONLY.class)
169-
private ResourceStorageEntryBase addEntry(Module module, String resourceName, ResourceStorageEntryBase newEntry, boolean isDirectory, boolean fromJar) {
169+
private void addEntry(Module module, String resourceName, boolean isDirectory, byte[] data, boolean fromJar, boolean isNegativeQuery) {
170170
VMError.guarantee(!BuildPhaseProvider.isAnalysisFinished(), "Trying to add a resource entry after analysis.");
171171
Module m = module != null && module.isNamed() ? module : null;
172172
if (m != null) {
@@ -175,58 +175,42 @@ private ResourceStorageEntryBase addEntry(Module module, String resourceName, Re
175175
synchronized (resources) {
176176
Pair<Module, String> key = createStorageKey(m, resourceName);
177177
ResourceStorageEntryBase entry = resources.get(key);
178+
if (isNegativeQuery) {
179+
if (entry == null) {
180+
resources.put(key, NEGATIVE_QUERY_MARKER);
181+
}
182+
return;
183+
}
184+
178185
if (entry == null || entry == NEGATIVE_QUERY_MARKER) {
179-
entry = newEntry == null ? new ResourceStorageEntry(isDirectory, fromJar) : newEntry;
180186
updateTimeStamp();
187+
entry = new ResourceStorageEntry(isDirectory, fromJar);
181188
resources.put(key, entry);
189+
} else {
190+
if (key.getLeft() != null) {
191+
// if the entry already exists, and it comes from a module, it is the same entry
192+
// that we registered at some point before
193+
return;
194+
}
182195
}
183-
return entry;
184-
}
185-
}
186196

187-
private void addEntry(Module module, String resourceName, boolean isDirectory, byte[] data, boolean fromJar) {
188-
ResourceStorageEntryBase entry = addEntry(module, resourceName, null, isDirectory, fromJar);
189-
entry.getData().add(data);
197+
entry.getData().add(data);
198+
}
190199
}
191200

192201
@Platforms(Platform.HOSTED_ONLY.class)
193202
public static void registerResource(String resourceName, InputStream is) {
194203
singleton().registerResource(null, resourceName, is, true);
195204
}
196205

197-
@Platforms(Platform.HOSTED_ONLY.class)
198-
public void registerResource(String resourceName, InputStream is, boolean fromJar) {
199-
registerResource(null, resourceName, is, fromJar);
200-
}
201-
202-
@Platforms(Platform.HOSTED_ONLY.class)
203-
public void registerResource(Module module, String resourceName, InputStream is) {
204-
registerResource(module, resourceName, is, true);
205-
}
206-
207206
@Platforms(Platform.HOSTED_ONLY.class)
208207
public void registerResource(Module module, String resourceName, byte[] resourceContent) {
209-
addEntry(module, resourceName, false, resourceContent, true);
208+
addEntry(module, resourceName, false, resourceContent, true, false);
210209
}
211210

212211
@Platforms(Platform.HOSTED_ONLY.class)
213212
public void registerResource(Module module, String resourceName, InputStream is, boolean fromJar) {
214-
addEntry(module, resourceName, false, inputStreamToByteArray(is), fromJar);
215-
}
216-
217-
@Platforms(Platform.HOSTED_ONLY.class)
218-
public void registerDirectoryResource(String resourceDirName, String content) {
219-
registerDirectoryResource(null, resourceDirName, content, true);
220-
}
221-
222-
@Platforms(Platform.HOSTED_ONLY.class)
223-
public void registerDirectoryResource(String resourceDirName, String content, boolean fromJar) {
224-
registerDirectoryResource(null, resourceDirName, content, fromJar);
225-
}
226-
227-
@Platforms(Platform.HOSTED_ONLY.class)
228-
public void registerDirectoryResource(Module module, String resourceDirName, String content) {
229-
registerDirectoryResource(module, resourceDirName, content, true);
213+
addEntry(module, resourceName, false, inputStreamToByteArray(is), fromJar, false);
230214
}
231215

232216
@Platforms(Platform.HOSTED_ONLY.class)
@@ -236,21 +220,16 @@ public void registerDirectoryResource(Module module, String resourceDirName, Str
236220
* specified directory, separated with new line delimiter and joined into one string which
237221
* is later converted into a byte array and placed into the resources map.
238222
*/
239-
addEntry(module, resourceDirName, true, content.getBytes(), fromJar);
240-
}
241-
242-
@Platforms(Platform.HOSTED_ONLY.class)
243-
public void registerIOException(String resourceName, IOException e, boolean linkAtBuildTime) {
244-
registerIOException(null, resourceName, e, linkAtBuildTime);
223+
addEntry(module, resourceDirName, true, content.getBytes(), fromJar, false);
245224
}
246225

247226
@Platforms(Platform.HOSTED_ONLY.class)
248227
public void registerIOException(Module module, String resourceName, IOException e, boolean linkAtBuildTime) {
249228
if (linkAtBuildTime) {
250229
if (SubstrateOptions.ThrowLinkAtBuildTimeIOExceptions.getValue()) {
251-
throw new RuntimeException("Resource " + resourceName + " from module " + module.getName() + " produced an IOException.", e);
230+
throw new RuntimeException("Resource " + resourceName + " from module " + moduleName(module) + " produced an IOException.", e);
252231
} else {
253-
LogUtils.warning("Resource " + resourceName + " from module " + module.getName() + " produced the following IOException: " + e.getClass().getTypeName() + ": " + e.getMessage());
232+
LogUtils.warning("Resource " + resourceName + " from module " + moduleName(module) + " produced the following IOException: " + e.getClass().getTypeName() + ": " + e.getMessage());
254233
}
255234
}
256235
Pair<Module, String> key = createStorageKey(module, resourceName);
@@ -267,7 +246,7 @@ public void registerNegativeQuery(String resourceName) {
267246

268247
@Platforms(Platform.HOSTED_ONLY.class)
269248
public void registerNegativeQuery(Module module, String resourceName) {
270-
addEntry(module, resourceName, NEGATIVE_QUERY_MARKER, false, false);
249+
addEntry(module, resourceName, false, null, false, true);
271250
}
272251

273252
@Platforms(Platform.HOSTED_ONLY.class)

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/localization/BundleContentSubstitutedLocalizationSupport.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@
3030
import java.util.ListResourceBundle;
3131
import java.util.Locale;
3232
import java.util.Map;
33+
import java.util.Optional;
3334
import java.util.ResourceBundle;
3435
import java.util.Set;
3536
import java.util.concurrent.ConcurrentHashMap;
3637
import java.util.concurrent.ForkJoinPool;
38+
import java.util.function.Function;
3739
import java.util.regex.Pattern;
3840
import java.util.regex.PatternSyntaxException;
3941

40-
import jdk.graal.compiler.debug.GraalError;
4142
import org.graalvm.nativeimage.Platform;
4243
import org.graalvm.nativeimage.Platforms;
4344

@@ -49,6 +50,7 @@
4950
import com.oracle.svm.core.util.UserError;
5051
import com.oracle.svm.core.util.VMError;
5152

53+
import jdk.graal.compiler.debug.GraalError;
5254
import sun.util.resources.OpenListResourceBundle;
5355
import sun.util.resources.ParallelListResourceBundle;
5456

@@ -172,8 +174,8 @@ public boolean isNotIncluded(String bundleName) {
172174
}
173175

174176
@Override
175-
public void prepareBundle(String bundleName, ResourceBundle bundle, Locale locale) {
176-
super.prepareBundle(bundleName, bundle, locale);
177+
public void prepareBundle(String bundleName, ResourceBundle bundle, Function<String, Optional<Module>> findModule, Locale locale) {
178+
super.prepareBundle(bundleName, bundle, findModule, locale);
177179
/* Initialize ResourceBundle.keySet eagerly */
178180
bundle.keySet();
179181
this.existingBundles.add(control.toBundleName(bundleName, locale));

0 commit comments

Comments
 (0)