簡體   English   中英

java.lang.IllegalAccessError: 無法訪問類,因為模塊沒有導出到未命名的模塊

[英]java.lang.IllegalAccessError: cannot access class because module does not export to unnamed module

我目前正在嘗試從 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 中,而另一個只是“最小”可行的產品')

不是重復這個,因為我(和我已經指出了這一點)嘗試--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;
    }
}

正如Nicolai這個問題回答所指出的那樣--add-exports java.base/jdk.internal.misc=ALL-UNNAMED必須在編譯 (javac)運行 (java) 代碼時完成。

有點晚了,但是因為我在嘗試 Java 和 JavaFX 的 OpenCV 教程時遇到了這個問題,所以我將分享對我有用的東西。

  1. 為了能夠編譯,我需要將 OpenJFX 和 OpenCV 庫添加到類路徑
  2. 不需要配置特殊的模塊編譯 - Eclipse 可以用 Java 11 很好地處理它
  3. 為了能夠運行,我創建了一個啟動快捷方式,添加如下 VM 參數

--module-path /javafx-sdk-11.0.2/lib

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM