java.lang.IllegalAccessError:无法访问类,因为模块未导出到未命名模块

问题描述 投票:0回答:4

我目前正在尝试从jdk-9.0.1中成功提取java.base.java.util.jar包,从中构建一个.jar并将该jar作为外部库导入到另一个项目中,以便我可以修改其中包含的类中的一些方法的行为。

我似乎成功地提取了包,因为我能够消除项目中所有可能的预编译错误并构建 .jar 工件。 我还可以将此 .jar 作为外部库导入到我的其他项目中。

编辑:来自 java.util.jar 外部的每个私有类(即:SharedSecrets)也被提取并放入 .jar 中

但是,当我尝试运行它时(通过替换

import java.util.jar.*;
以使用我自己的版本) 我收到此错误:
java.lang.IllegalAccessError: class SharedSecrets (in unnamed module @0x2b546384) cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @0x2b546384

我尝试添加这个:

--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED
和添加这个:
--add-exports=java.base/jdk.internal.misc.Unsafe=ALL-UNNAMED
到两者的编译选项,由提取的java.util.jar包组成的项目和我想将其导入为外部库的项目,没有一个起作用-> 错误仍然存在。

编译选项中的所有其他

--add-exports
在这两个项目上都可以正常工作。

我做错了什么?我必须更改什么才能使其正常工作?

注意:如果不清楚,请随时询问!

编辑:我尝试使用自己的“java.util.jar”而不是官方的代码(注意目前两者是相同的,唯一的区别是一个保留在 jdk 中,而另一个只是“最小可行产品')

这不是this的重复,因为我(并且我已经指出了)尝试了在另一个问题中建议作为答案的--add-exports

错误发生在调用JarFile构造函数的第4行,该构造函数不会调用jdk中的构造函数,而是调用我导入的自制库中的构造函数。

public boolean verifyJar(String jarName) throws Exception { boolean anySigned = false; // if there exists entry inside jar signed Map<String, String> digestMap = new HashMap<>(); Map<String, PKCS7> sigMap = new HashMap<>(); try (JarFile jf = new JarFile(jarName, true)) { // error Vector<JarEntry> entriesVec = new Vector<>(); byte[] buffer = new byte[8192]; Enumeration<JarEntry> entries = jf.entries(); while (entries.hasMoreElements()) { JarEntry je = entries.nextElement(); entriesVec.addElement(je); try (InputStream is = jf.getInputStream(je)) { String name = je.getName(); if (MySignatureFileVerifier.isSigningRelated(name) && MySignatureFileVerifier.isBlockOrSF(name)) { String alias = name.substring(name.lastIndexOf('/') + 1, name.lastIndexOf('.')); try { if (name.endsWith(".SF")) { Manifest sf = new Manifest(is); for (Object obj : sf.getMainAttributes().keySet()) { String key = obj.toString(); if (key.endsWith("-Digest-Manifest")) { digestMap.put(alias, key.substring(0, key.length() - 16)); break; } } } else { sigMap.put(alias, new PKCS7(is)); } } catch (IOException ioe) { throw ioe; } } else { while (is.read(buffer, 0, buffer.length) != -1) { // we just read. this will throw a SecurityException // if a signature/digest check fails. } } } } Manifest man = jf.getManifest(); boolean hasSignature = false; if (man != null) { Enumeration<JarEntry> e = entriesVec.elements(); while (e.hasMoreElements()) { JarEntry je = e.nextElement(); String name = je.getName(); hasSignature = hasSignature || MySignatureFileVerifier.isBlockOrSF(name); CodeSigner[] signers = getCodeSigners(je, sigMap.get("SIGNER")); boolean isSigned = (signers != null); anySigned |= isSigned; } } if (man == null) { System.out.println(); } // Even if the verbose option is not specified, all out strings // must be generated so seeWeak can be updated. if (!digestMap.isEmpty() || !sigMap.isEmpty()) { for (String s : digestMap.keySet()) { PKCS7 p7 = sigMap.get(s); if (p7 != null) { String history; try { SignerInfo si = p7.getSignerInfos()[0]; X509Certificate signer = si.getCertificate(p7); String digestAlg = digestMap.get(s); String sigAlg = AlgorithmId.makeSigAlg( si.getDigestAlgorithmId().getName(), si.getDigestEncryptionAlgorithmId().getName()); PublicKey key = signer.getPublicKey(); PKCS7 tsToken = si.getTsToken(); if (tsToken != null) { SignerInfo tsSi = tsToken.getSignerInfos()[0]; X509Certificate tsSigner = tsSi.getCertificate(tsToken); byte[] encTsTokenInfo = tsToken.getContentInfo().getData(); TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo); PublicKey tsKey = tsSigner.getPublicKey(); String tsDigestAlg = tsTokenInfo.getHashAlgorithm().getName(); String tsSigAlg = AlgorithmId.makeSigAlg( tsSi.getDigestAlgorithmId().getName(), tsSi.getDigestEncryptionAlgorithmId().getName()); } } catch (Exception e) { throw e; } } } } System.out.println(); if (!anySigned) { if (hasSignature) { System.out.println("jar.treated.unsigned"); } else { System.out.println("jar.is.unsigned"); return false; } } else { System.out.println("jar.verified."); return true; } return false; } catch (Exception e) { throw e; } }
    
java java-9 illegalaccessexception
4个回答
18
投票
正如

Nicolai'sthis问题的回答所指出的,--add-exports java.base/jdk.internal.misc=ALL-UNNAMED

必须在编译(javac)
运行(java)代码时完成。


1
投票
有点晚了,但自从我在尝试 Java 和 JavaFX 的 OpenCV 教程时遇到了这个问题,我将分享对我有用的方法。

    为了能够编译,我需要将 OpenJFX 和 OpenCV 库添加到类路径中
  1. 无需配置特殊模块编译 - Eclipse 在 Java 11 中可以很好地处理它
  2. 为了能够运行,我创建了一个启动快捷方式,添加了如下所示的虚拟机参数
--模块路径/javafx-sdk-11.0.2/lib

--add-modules=javafx.controls,javafx.fxml

--add-exports java.base/jdk.internal.misc=ALL-UNNAMED


1
投票
我正在分享我的解决方案。我用不同的包遇到了这个问题。然而,这就是我解决这个问题的方法(我正在使用 Eclipse):

假设我的类位于名为 stack.overflow.test 的包中,并且我的模块名称为 stack,

我按照

https://jenkov.com/tutorials/java/modules.html 的说明将“exports Overflow.test”添加到 module-info.java 文件中


0
投票
尝试了 stackoverflow 以及其他类似平台上提供的许多相关解决方案,但没有任何帮助。终于得到了这个汇合链接,它有助于解决问题:

https://confluence.atlassian.com/jirakb/health-check-java-recorder-jfr-failed-1167750282.html

© www.soinside.com 2019 - 2024. All rights reserved.