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

Error while resolving class file for ... via JavaSE-19 #356

Closed
jukzi opened this issue Oct 8, 2022 · 7 comments
Closed

Error while resolving class file for ... via JavaSE-19 #356

jukzi opened this issue Oct 8, 2022 · 7 comments

Comments

@jukzi
Copy link
Contributor

jukzi commented Oct 8, 2022

with JRE 19 i get errors in an oomphed workspace

eclipse.buildId=4.26.0.I20221007-1800
java.version=19
java.vendor=Eclipse Adoptium
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=de_DE

org.eclipse.pde.api.tools
Error while resolving class file for: javax.security.auth.spi.LoginModule via JavaSE-19

org.eclipse.core.runtime.CoreException: Failed to open archive: C:\Users\JKubitz\eclipseDev\platform2022-10-08\eclipse\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_19.0.0.v20221005-1658\jre\jmods\java.base.jmod
	at org.eclipse.pde.api.tools.internal.model.ApiElement.abort(ApiElement.java:104)
	at org.eclipse.pde.api.tools.internal.model.ArchiveApiTypeContainer.init(ArchiveApiTypeContainer.java:286)
	at org.eclipse.pde.api.tools.internal.model.ArchiveApiTypeContainer.findTypeRoot(ArchiveApiTypeContainer.java:228)
	at org.eclipse.pde.api.tools.internal.model.AbstractApiTypeContainer.findTypeRoot(AbstractApiTypeContainer.java:110)
	at org.eclipse.pde.api.tools.internal.util.Util.getClassFile(Util.java:599)
	at org.eclipse.pde.api.tools.internal.model.ApiType.resolveSuperType(ApiType.java:299)
	at org.eclipse.pde.api.tools.internal.model.ApiType.getSuperInterfaces(ApiType.java:258)
	at org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator.collectAllInterfaces(ClassFileComparator.java:921)
	at org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator.getInterfacesSet(ClassFileComparator.java:2073)
	at org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator.checkSuperInterfaces(ClassFileComparator.java:299)
	at org.eclipse.pde.api.tools.internal.comparator.ClassFileComparator.getDelta(ClassFileComparator.java:1211)
	at org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator$2.visit(ApiComparator.java:771)
	at org.eclipse.pde.api.tools.internal.model.ArchiveApiTypeContainer.accept(ArchiveApiTypeContainer.java:198)
	at org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator.internalCompare(ApiComparator.java:655)
	at org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator.compare(ApiComparator.java:289)
	at org.eclipse.pde.api.tools.internal.provisional.comparator.ApiComparator.compare(ApiComparator.java:315)
	at org.eclipse.pde.api.tools.internal.builder.BaseApiAnalyzer.checkCompatibility(BaseApiAnalyzer.java:1512)
	at org.eclipse.pde.api.tools.internal.builder.BaseApiAnalyzer.analyzeComponent(BaseApiAnalyzer.java:269)
	at org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder.buildAll(ApiAnalysisBuilder.java:944)
	at org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder.work(ApiAnalysisBuilder.java:426)
	at org.eclipse.pde.api.tools.internal.builder.ApiAnalysisBuilder$ApiAnalysisJob.run(ApiAnalysisBuilder.java:578)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: java.nio.file.NoSuchFileException: C:\Users\JKubitz\eclipseDev\platform2022-10-08\eclipse\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_19.0.0.v20221005-1658\jre\jmods\java.base.jmod
	at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
	at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
	at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
	at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:53)
	at java.base/sun.nio.fs.WindowsFileAttributeViews$Basic.readAttributes(WindowsFileAttributeViews.java:38)
	at java.base/sun.nio.fs.WindowsFileSystemProvider.readAttributes(WindowsFileSystemProvider.java:199)
	at java.base/java.nio.file.Files.readAttributes(Files.java:1849)
	at java.base/java.util.zip.ZipFile$Source.get(ZipFile.java:1279)
	at java.base/java.util.zip.ZipFile$CleanableResource.<init>(ZipFile.java:710)
	at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:243)
	at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:172)
	at java.base/java.util.zip.ZipFile.<init>(ZipFile.java:143)
	at org.eclipse.pde.api.tools.internal.model.ArchiveApiTypeContainer.init(ArchiveApiTypeContainer.java:284)
	... 20 more


@merks
Copy link
Contributor

merks commented Oct 10, 2022

I get this same error using with a Java 17 JRE. The problem is fundamentally caused by a bad assumption in the following code. :

public ArchiveApiTypeContainer(IApiElement parent, String path) {
super(parent, IApiElement.API_TYPE_CONTAINER, path);
this.fLocation = path;
if (path.endsWith("jrt-fs.jar")) { //$NON-NLS-1$
IPath newPath = new Path(path);
newPath = newPath.removeLastSegments(2).addTrailingSeparator();
newPath = newPath.append("jmods").append("java.base.jmod"); //$NON-NLS-1$ //$NON-NLS-2$
this.fLocation = newPath.toOSString();
}
}

In particular it assumes that the JRE is a JDK (with java.home/mods/*.jmod) and not a JRE as produced by jlink (with java.home/lib/modules)

The following also makes that same bad assumption but here there is an existence test:

protected List<IApiTypeContainer> createApiTypeContainers() throws CoreException {
List<IApiTypeContainer> libs = new ArrayList<>(fLibraries.length);
for (LibraryLocation lib : fLibraries) {
libs.add(new ArchiveApiTypeContainer(this, lib.getSystemLibraryPath().toOSString()));
}
if (fLibraries.length == 0) {
if (fLocation != null) {
IPath newPath = new Path(fLocation);
newPath = newPath.append("jmods").append("java.base.jmod"); //$NON-NLS-1$ //$NON-NLS-2$
if (newPath.toFile().exists()) {
libs.add(new ArchiveApiTypeContainer(this, newPath.toOSString()));
}
}
}
return libs;
}

The class should be using logic similar to what's in org.eclipse.jdt.internal.compiler.util.JRTUtil. I.e., using java.nio.file.FileSystem which could also be used for jar: URIs to read regular jars so that both cases are handled uniformly, for example:

	public ArchiveApiTypeContainer(IApiElement parent, String path) {
		super(parent, IApiElement.API_TYPE_CONTAINER, path);
		this.fLocation = path;
		if (path.endsWith("jrt-fs.jar")) { //$NON-NLS-1$
			IPath newPath = new Path(path);
			IPath jrePath = newPath.removeLastSegments(2).addTrailingSeparator();
			newPath = jrePath.append("jmods").append("java.base.jmod"); //$NON-NLS-1$ //$NON-NLS-2$
			if (Files.isRegularFile(java.nio.file.Path.of(newPath.toOSString()))) {
				this.fLocation = newPath.toOSString();
			} else {
				try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"),
						Collections.singletonMap("java.home", jrePath.toOSString()))) {
					System.out.println("Modules of " + jrePath);
					Files.list(fs.getPath("/modules")).forEach(System.out::println);
					System.out.println();
					System.out.println("Root packages of " + jrePath);
					Files.list(fs.getPath("/modules/java.base")).forEach(System.out::println);
					System.out.println("All of " + jrePath);
					System.out.println();
					Files.walk(fs.getPath("/modules/java.base")).forEach(System.out::println);
					System.out.println();
					System.out.println();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

@iloveeclipse
Copy link
Member

Note 1: try (FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), is not good because it would close file system at the end - while it most likely be still in use by JDT.

Ideally PDE would simply re-use org.eclipse.jdt.internal.compiler.util.JrtFileSystem and if there is something missing, just add the missing functionality.

Note 2: PDE & JDT as part of the Eclipse SDK both require Java SDK to work properly, JRE is not enough, and that is not new.

@jukzi
Copy link
Contributor Author

jukzi commented Oct 10, 2022

JRE is not enough, and that is not new.

then oomph should install JDK instead.

@merks
Copy link
Contributor

merks commented Oct 10, 2022

@iloveeclipse

I'm investigating how to implement this correctly and indeed, closing the JRT file system is bad!

I'm not sure the basis of your assertion that a JDK is required. All the packages including the Java package ship with a JustJ JRE 17 and hence the configured JRE in any new workspace by default looks like this:

image

One can even step into the JRE's source code:

image

What other things do you believe don't function properly, because packages have been shipping like this for several releases and no one ever complained that something doesn't work...

@iloveeclipse
Copy link
Member

I remember we had recurring troubles in JDT / debug area, where JRE was not sufficient, same with CtSym.java code not finding proper release info because "ct.sym" file was missing in JRE.

What is packaged into "justj full" bundle? Isn't that something more then just JRE?

@merks
Copy link
Contributor

merks commented Oct 10, 2022

I know there were problems but as far as I know, there are no longer problems, other than this new one that I didn't know about.

The ct.sym is present:

$find . -name ct.sym
./plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20221004-1257/jre/lib/ct.sym
./plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_18.0.1.v20220515-1614/jre/lib/ct.sym
./plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_19.0.0.v20221005-1658/jre/lib/ct.sym

All the modules are present in the full JRE, but are packaged differently, and the jrt file system doesn't care how it's packaged. The src.zip is included too so that debugging works well:

$find . -name src.zip
./plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_17.0.4.v20221004-1257/jre/lib/src.zip
./plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_18.0.1.v20220515-1614/jre/lib/src.zip
./plugins/org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_19.0.0.v20221005-1658/jre/lib/src.zip

I'll come up with PR...

@iloveeclipse
Copy link
Member

I believe the issues we saw before were seen by users of system JRE's on Linux / Windows that were installed manually/via system updates.
Not sure they differ from "justj" variant we ship, I've never used any of them, I always prefer / need full SDK anyway.

merks added a commit to merks/eclipse.pde that referenced this issue Oct 11, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.

eclipse-pde#356
merks added a commit to merks/eclipse.pde that referenced this issue Oct 11, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.  Classes from
the JDK will no longer be prefixed with classes.*.

eclipse-pde#356
merks added a commit to merks/eclipse.pde that referenced this issue Oct 11, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.  Classes from
the JDK will no longer be prefixed with classes.*.

eclipse-pde#356
merks added a commit to merks/eclipse.pde that referenced this issue Oct 11, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.  Classes from
the JDK will no longer be prefixed with classes.*.

eclipse-pde#356
merks added a commit to merks/eclipse.pde that referenced this issue Oct 12, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.  Classes from
the JDK will no longer be prefixed with classes.*.

eclipse-pde#356
merks added a commit to merks/eclipse.pde that referenced this issue Oct 12, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.  Classes from
the JDK will no longer be prefixed with classes.*.

eclipse-pde#356
merks added a commit that referenced this issue Oct 12, 2022
Instead of assuming that modules are represented as *.jmod, which is
only the case for a JDK but not for a JRE, the jrt file system should be
used.  In addition, jar files should  use the jar file system, to
uniformly handle both cases.  The JRT approach also allows loading all
the modules of the JDK/JRE not just the java.base module.  Classes from
the JDK will no longer be prefixed with classes.*.

#356
@merks merks closed this as completed Oct 12, 2022
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

3 participants