19

I am currently trying to successfully extract the java.base.java.util.jar package from the jdk-9.0.1, building a .jar out of it and importing the jar as external library into another project, so that I can modify the behavior of some of the methods from the classes contained in it.

I seem to be successful at extracting the package, as I am able to eradicate all possible pre-compilation-errors in the project and build the .jar artifact. I can also import this .jar as external library in my other project.

Edit: every private class from outside java.util.jar (i.e.: SharedSecrets) that was needed was also extracted and put in the .jar

However, when I try to run it (by replacing the import java.util.jar.*; in order to use my own version of it) I get this error: 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

I tried both adding this: --add-exports=java.base/jdk.internal.misc=ALL-UNNAMED and adding this: --add-exports=java.base/jdk.internal.misc.Unsafe=ALL-UNNAMED to the Compilation options of both, the project consisting of the extracted java.util.jar package and the project I want to import it as external library, none worked -> the error persists.

All other --add-exports which are in the Compilation Options do work fine on both projects.

What am I doing wrong? What do I have to change in order for it to work?

N.B.: if things are unclear, feel free to ask!

Edit: The code where I try to use my own 'java.util.jar' instead of the official one (note at the moment both are identical, the only difference is that one remains inside the jdk while the other is just the 'minimal viable product')

This is not a duplicate of this as I (and I already pointed that out) tried the --add-exports which are suggested as answer in the other question.

The error occurs in the 4. line where the JarFile constructor is called which will not call the one from the jdk but the one from the selfmade library I imported.

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;
 }
}
asked Dec 5, 2018 at 13:45
12
  • 3
    jdk.internal.miscjdk.internal.util. Commented Dec 5, 2018 at 13:54
  • 1
    jdk.internal.util.misc still doesn’t match jdk.internal.misc. Commented Dec 5, 2018 at 14:02
  • 3
    what do you mean extracted it? I think you've tried to copy the internal class to your module/package. And by modular project, I was asking the project that you're creating. I suspect that is what ends up in the classpath. Commented Dec 5, 2018 at 14:19
  • 3
    No, please don't do such things... if you really want some implementation out of the class, look out for alternatives. Copying an internal class is like hijacking the code and then you're asking why is the hijacked code not working without even sharing the details of what your code looks like. Commented Dec 5, 2018 at 14:26
  • 2
    I am not sure, where are you heading towards. But, just to remind you of what Alan said - stackoverflow.com/questions/53610904/… Commented Dec 5, 2018 at 14:53

3 Answers 3

21

As pointed out by Nicolai's answer to this question --add-exports java.base/jdk.internal.misc=ALL-UNNAMED has to be done when compiling (javac) and when running (java) the code.

answered Dec 6, 2018 at 8:47
Sign up to request clarification or add additional context in comments.

6 Comments

wow, I've spent 2 hours figuring out that I should add it when running java.
Can we add this in maven build
@AkshayHazari I think you can set compiler args directly: maven.apache.org/plugins/maven-compiler-plugin/examples/…
@whme Yes I figured there were some issues with my java version in local even after setting the the version using sdkman
If your application is modular, replace ALL-UNNAMED with the name of your module.
|
1

A little late, but I since I bumped into this issue when trying out the OpenCV tutorial for Java and JavaFX, I will share what worked for me.

  1. To be able to compile I needed to add the OpenJFX and OpenCV libraries to classpath
  2. Not necessary to configure special module compilation - Eclipse handles it well with Java 11
  3. To be able to run I created a launch shortcut that adds the VM arguments as below

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

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

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

answered Mar 7, 2020 at 18:56

Comments

1

I am sharing my solution around this issue. I faced this problem with a different package. However, this is how I came around it (I am using Eclipse):

Assuming that my classes are in a package called stack.overflow.test and my module name is stack,

I added "exports overflow.test" to module-info.java file following the instructions from https://jenkov.com/tutorials/java/modules.html

answered Oct 12, 2022 at 16:06

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.