67
votes

For this two imports;

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

I got this error:

Access restriction: The type BASE64Decoder is not accessible due to restriction on required library C:\Program Files\Java\jre6\lib\rt.jar

How can I resolve this error?

13

13 Answers

66
votes

That error is caused by your Eclipse configuration. You can reduce it to a warning. Better still, use a Base64 encoder that isn't part of a non-public API. Apache Commons has one, or when you're already on Java 1.8, then use java.util.Base64.

124
votes

Go to Window-->Preferences-->Java-->Compiler-->Error/Warnings.
Select Deprecated and Restricted API. Change it to warning.
Change forbidden and Discouraged Reference and change it to warning. (or as your need.)

37
votes

Sure - just don't use the Sun base64 encoder/decoder. There are plenty of other options available, including Apache Codec or this public domain implementation.

Then read why you shouldn't use sun.* packages.

24
votes

Java 6 ships the javax.xml.bind.DatatypeConverter. This class provides two static methods that support the same decoding & encoding:

parseBase64Binary() / printBase64Binary()

Update: Since Java 8 we now have a much better Base64 Support.

Use this and you will not need an extra library, like Apache Commons Codec.

5
votes

Yup, and sun.misc.BASE64Decoder is way slower: 9x slower than java.xml.bind.DatatypeConverter.parseBase64Binary() and 4x slower than org.apache.commons.codec.binary.Base64.decodeBase64(), at least for a small string on Java 6 OSX.

Below is the test program I used. With Java 1.6.0_43 on OSX:

john:password = am9objpwYXNzd29yZA==
javax.xml took 373: john:password
apache took    612: john:password
sun took       2215: john:password

Btw that's with commons-codec 1.4. With 1.7 it seems to get slower:

javax.xml took 377: john:password
apache took    1681: john:password
sun took       2197: john:password

Didn't test Java 7 or other OS.

import javax.xml.bind.DatatypeConverter;
import org.apache.commons.codec.binary.Base64;
import java.io.IOException;

public class TestBase64 {
    private static volatile String save = null;
    public static void main(String argv[]) {
        String teststr = "john:password";
        String b64 = DatatypeConverter.printBase64Binary(teststr.getBytes());
        System.out.println(teststr + " = " + b64);
        try {
            final int COUNT = 1000000;
            long start;
            start = System.currentTimeMillis();
            for (int i=0; i<COUNT; ++i) {
                save = new String(DatatypeConverter.parseBase64Binary(b64));
            }
            System.out.println("javax.xml took "+(System.currentTimeMillis()-start)+": "+save);
            start = System.currentTimeMillis();
            for (int i=0; i<COUNT; ++i) {
                save = new String(Base64.decodeBase64(b64));
            }
            System.out.println("apache took    "+(System.currentTimeMillis()-start)+": "+save);
            sun.misc.BASE64Decoder dec = new sun.misc.BASE64Decoder();
            start = System.currentTimeMillis();
            for (int i=0; i<COUNT; ++i) {
                save = new String(dec.decodeBuffer(b64));
            }
            System.out.println("sun took       "+(System.currentTimeMillis()-start)+": "+save);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}
5
votes

I had this problem on jdk1.6.0_37. This is the only JDE/JRE on my system. I don't know why, but the following solved the problem:

Project -> Properties -> Java Build Path - > Libraries

Switch radio button from Execution environment to Alernate JRE. This selects the same jdk1.6.0_37, but after clean/build the compile error disappeared.

Maybe clarification in answer from ram (Mar 16 at 9:00) has to do something with that.

3
votes

This error is because of you are importing below two classes import sun.misc.BASE64Encoder; import sun.misc.BASE64Decoder;. Maybe you are using encode and decode of that library like below.

new BASE64Encoder().encode(encVal);
newBASE64Decoder().decodeBuffer(encryptedData);

Yeah instead of sun.misc.BASE64Encoder you can import java.util.Base64 class.Now change the previous encode method as below:

encryptedData=Base64.getEncoder().encodeToString(encryptedByteArray);

Now change the previous decode method as below

byte[] base64DecodedData = Base64.getDecoder().decode(base64EncodedData);

Now everything is done , you can save your program and run. It will run without showing any error.

2
votes
  1. Go to the Build Path settings in the project properties.
  2. Remove the JRE System Library
  3. Add it back; Select "Add Library" and select the JRE System Library. The default worked for me.

This works because you have multiple classes in different jar files. Removing and re-adding the jre lib will make the right classes be first. If you want a fundamental solution make sure you exclude the jar files with the same classes.

2
votes

Be careful, sun.misc.BASE64Decoder is not available in JDK-13

2
votes

This error (or warning in later versions) occurs because you are compiling against a Java Execution Environment. This shows up as JRE System library [CDC-1.0/Foundation-1.0] in the Build path of your Eclipse Java project. Such environments only expose the Java standard API instead of all the classes within the runtime. This means that the classes used to implement the Java standard API are not exposed.

You can allow access to these particular classes using access rules, you could configure Eclipse to use the JDK directly or you could disable the error. You would however be hiding a serious error as Sun internal classes shouldn't be used (see below for a short explanation).


Java contains a Base64 class in the standard API since Java 1.8. See below for an example how to use it:

Java 8 import statement:

import java.util.Base64;

Java 8 example code:

// create a byte array containing data (test)
byte[] binaryData = new byte[] { 0x64, 0x61, 0x74, 0x61 };
// create and configure encoder (using method chaining) 
Base64.Encoder base64Encoder = Base64.getEncoder().withoutPadding();
// encode to string (instead of a byte array containing ASCII)
String base64EncodedData = base64Encoder.encodeToString(binaryData);

// decode using a single statement (no reuse of decoder)
// NOTE the decoder won't fail because the padding is missing
byte[] base64DecodedData = Base64.getDecoder().decode(base64EncodedData);

If Java 8 is not available a library such as Apache Commons Codec or Guava should be used.


Sun internal classes shouldn't be used. Those classes are used to implement Java. They have got public methods to allow instantiation from other packages. A good build environment however should protect you from using them.

Using internal classes may break compatibility with future Java SE runtimes; the implementation and location of these classes can change at any time. It should be strongly discouraged to disable the error or warning (but the disabling of the error is suggested in previous answers, including the two top voted ones).

1
votes

I am using unix system.

In eclipse project-> Properties -> Java Compiler -> Errors/Warning -> Forbidden Access(access rule) -> Turn it to warning/Ignore(Previously it was set to Error).

0
votes

I know this is very Old post. Since we don't have any thing sun.misc in maven we can easily use

StringUtils.newStringUtf8(Base64.encodeBase64(encVal)); From org.apache.commons.codec.binary.Base64

-1
votes

Add base64decoder jar and try these imports:

import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;