Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[native-image] Classpath not honored when adding resources #1988

Closed
ozppupbg opened this issue Dec 13, 2019 · 5 comments
Closed

[native-image] Classpath not honored when adding resources #1988

ozppupbg opened this issue Dec 13, 2019 · 5 comments
Assignees

Comments

@ozppupbg
Copy link

Hello,

I have an application, which reads its version information from the META-INF/MANIFEST.MF file. I added this file to the image resources, but the file I get at runtime is not from my jar.

I checked the resource inclusion with the option "-H:Log=registerResource:" and see 5 or 6 MANIFEST.MF files added.
Of course the last one wins and is the one present in the native image. As my only input is a single jar file I would have expected my version be in the image. But interesting enough it is neither the first MANIFEST.MF file in the classpath, but one in the middle.
As all jar files except mine, are from "graalvm/lib/svm/builder/" I don't see an easy way to fix this from my side.

I'm using the latest GraalVM Community Edition 19.3.0 amd64 for Linux.

Thank you!

Regards,

Oz

@jaikiran
Copy link
Contributor

Hello @ozppupbg,

I have an application, which reads its version information from the META-INF/MANIFEST.MF file.

Which API do you use to get hold of that file? Can you paste that snippet? Is it the ClassLoader.getResource or ClassLoader.getResourceAsStream? Can you try ClassLoader.getResources instead?

@ozppupbg
Copy link
Author

ozppupbg commented Feb 4, 2020

Hello @jaikiran,

I tried clazz.getResource, but for now have settled with manifestPath = "resource:META-INF/MANIFEST.MF"; manifest = new Manifest(new URL(manifestPath).openStream());, which should work, as it is native-image specific.

By now I also verified, that all included MANIFEST.MF files seem to present in the binary as strings.

These should be the code parts resposible for getting the resource file if I use this method:

public InputStream getInputStream() throws IOException {
Resources.ResourcesSupport support = ImageSingletons.lookup(Resources.ResourcesSupport.class);
// remove "protcol:" from url to get the resource name
String resName = url.toString().substring(1 + JavaNetSubstitutions.RESOURCE_PROTOCOL.length());
final List<byte[]> bytes = support.resources.get(resName);
if (bytes == null || bytes.size() < 1) {
return null;
} else {
return new ByteArrayInputStream(bytes.get(0));
}
}

@Platforms(Platform.HOSTED_ONLY.class)
public static void registerResource(String name, InputStream is) {
ResourcesSupport support = ImageSingletons.lookup(ResourcesSupport.class);
byte[] arr = new byte[4096];
int pos = 0;
try {
for (;;) {
if (pos == arr.length) {
byte[] tmp = new byte[arr.length * 2];
System.arraycopy(arr, 0, tmp, 0, arr.length);
arr = tmp;
}
int len = is.read(arr, pos, arr.length - pos);
if (len == -1) {
break;
}
pos += len;
}
} catch (IOException ex) {
throw VMError.shouldNotReachHere(ex);
}
byte[] res = new byte[pos];
System.arraycopy(arr, 0, res, 0, pos);
List<byte[]> list = support.resources.get(name);
if (list == null) {
list = new ArrayList<>();
support.resources.put(name, list);
}
list.add(res);
}
public static List<byte[]> get(String name) {
return ImageSingletons.lookup(ResourcesSupport.class).resources.get(name);
}

If multiple resources with the same name are registered, the first one should be "winning".

Regards,

Oz

@peter-hofer
Copy link
Member

Thank you for your report @ozppupbg and apologies for the late reply. The resources should indeed be in the order in which they are found on the class path for ClassLoader.getResources and getSystemResources, and getResource and getSystemResource should pick the first one. However, this is still different to how multiple ClassLoaders (can) provide resources and might not be a universal solution.

@peter-hofer peter-hofer assigned vjovanov and unassigned peter-hofer Apr 12, 2021
@jovanstevanovic
Copy link
Member

PR #3315 will fix this issue.

jovanstevanovic added a commit to jovanstevanovic/graal that referenced this issue May 29, 2021
jovanstevanovic added a commit to jovanstevanovic/graal that referenced this issue May 31, 2021
jovanstevanovic added a commit to jovanstevanovic/graal that referenced this issue Jun 1, 2021
jovanstevanovic added a commit to jovanstevanovic/graal that referenced this issue Jun 7, 2021
jovanstevanovic added a commit to jovanstevanovic/graal that referenced this issue Jun 7, 2021
jovanstevanovic added a commit to jovanstevanovic/graal that referenced this issue Jun 8, 2021
@jovanstevanovic
Copy link
Member

The PR that fixes this problem is on a master for a while, so I'm going to close this issue.

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

No branches or pull requests

5 participants