| Summary: | platform:/plugin/ URLs do not resolve items within embedded jars | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Brian de Alwis <bsd> |
| Component: | Runtime | Assignee: | platform-runtime-inbox <platform-runtime-inbox> |
| Status: | RESOLVED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | remy.suen |
| Version: | 4.2 | ||
| Target Milestone: | 3.8 M5 | ||
| Hardware: | PC | ||
| OS: | Mac OS X - Carbon (unsup.) | ||
| Whiteboard: | |||
With E4, we write out a serialized form of the UI to be restored on subsequent sessions. Icons and part implementation classes are referred to using URIs. As we can't control when a user might start with -clean, or move the serialized model to another workspace (or another machine), we have some code that rewrites the bundleentry and bundleresource style URLs into their platform:/plugin equivalents. This works fine for bundleentry:// URLs (i.e., they're able to be resolved from the bundle directly), but we've discovered that it doesn't work for bundleresource:// URLs, which reference items found within embedded jars. In my case, the code is referencing icons that are stored in embedded .jar files; this is out of my control. The issue here is that Equinox's PlatformURLPluginConnection uses Bundle#getEntry(). Ideally, I'd like to change PlatformURLPluginConnection#resolve() to try Bundle#getResource() if the URL can't be resolved by a getEntry() — as the code says at the bottom of the method, it creates a a URL that will force a FileNotFoundException anyways: protected URL resolve() throws IOException { String spec = url.getFile().trim(); Object[] obj = parse(spec, url); Bundle b = (Bundle) obj[0]; String path = (String) obj[1]; URL result = b.getEntry(path); if (result != null || "/".equals(path)) //$NON-NLS-1$ return result; // if the result is null then force the creation of a URL that will throw FileNotFoundExceptions return new URL(b.getEntry("/"), path); //$NON-NLS-1$ } This will also a problem for anybody trying to reference a class that's defined in an embedded jar file with a platform:/plugin URL. It seems strange that I import and use a class that is contained in an embedded jar, but cannot resolve tht class through a URL. Or rather, that the layout of the bundle affects whether an item can be resolved or not. The fix is straightforward: --- org.eclipse.equinox.common/src/org/eclipse/core/internal/runtime/PlatformURLPluginConnection.java .orig 2011-12-16 14:31:02.000000000 -0500 +++ org.eclipse.equinox.common/src/org/eclipse/core/internal/runtime/PlatformURLPluginConnection.java 2011-12-16 14:22:37.000000000 -0500 @@ -78,6 +79,10 @@ URL result = b.getEntry(path); if (result != null || "/".equals(path)) //$NON-NLS-1$ return result; + // try resolving the path through the classloader + result = b.getResource(path); + if (result != null) + return result; // if the result is null then force the creation of a URL that will throw FileNotFoundExceptions return new URL(b.getEntry("/"), path); //$NON-NLS-1$ }