75

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?

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
karikari
  • 6,627
  • 16
  • 64
  • 79

15 Answers15

127

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.)

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Nikunj
  • 3,100
  • 2
  • 20
  • 19
  • Same problem occurs when trying to use sun.misc.Signal these days as well. Answering the actual question solved my issue as well. – AndrewPK Apr 04 '12 at 15:22
  • 2
    It may have "answered the question" but masking an error as a warning is a poor solution (_though not bad enough to downvote_). [@Orism](http://stackoverflow.com/a/12090601/573057)'s answer below using `javax.xml.bind.DatatypeConverter` **solves the problem** without additional dependencies where JDK >= 1.6 – earcam Jun 13 '13 at 04:32
  • 3
    @earcam It's only an error because of an over-enthusastic Eclipse default configuration. The Java compiler doesn't consider it an error and neither does NetBeans. – user207421 Jan 14 '14 at 07:28
  • 1
    @EJP agreed - an error is fatal is and this certainly shouldn't be, but as per Jon Skeet's answer - it's a valid and serious warning of runtime portability. Anyway think this is largely historical now (2011==Indigo), in Kepler the default is warning (not sure since which version). – earcam Jan 14 '14 at 22:12
69

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user207421
  • 305,947
  • 44
  • 307
  • 483
  • 2
    @downvoter Please explain, unless you want your downvote to be taken as mere site vandalism. – user207421 Nov 09 '12 at 04:02
  • I guess it was downvoted in favor of nIKUNJ or Jon Skeeter answers. – Vladimir Zhilyaev Jan 25 '13 at 09:54
  • 3
    @VladimirZhilyaev That's not what the downvote system is for. It is expressly for 'this answer is not useful'. If there's a better answer it should certainly be upvoted, but downvotes should be applied to incorrect or irrelevant answers. It's clear that some people have other agendas. – user207421 Jan 14 '14 at 07:59
  • 2
    Also note that this particular import only works with Oracle JVMs. Other vendors will most likely not have this class causing your program to break. – Thorbjørn Ravn Andersen Mar 12 '14 at 16:07
  • @EJP Changing to warning solves the problem but will work without any problem in future like will it compile and build normally. – smali Jul 26 '14 at 05:49
  • To update config: Window->Perferences->Java->Compiler->Errors/Warnings->Deprecated and restricted API->Forbidden reference (set to "Warning" instead of "Error" – The Camster Aug 27 '14 at 20:47
  • In Java 8 you don't need to use an external base 64 codec anymore, so I've [added an answer](http://stackoverflow.com/a/28628476/589259) that includes a code fragment and reasoning why internal classes should not be used. Java 7 is almost end of support now. – Maarten Bodewes Feb 20 '15 at 12:48
  • 1
    There is no valid reason for the downvote. @EJP stated the cause:" caused by your Eclipse configuration.", Solution 1:"You can reduce it to a warning", Solution 2:"use Apache Commons" ....stop the random downvoting it sucks. – Jeryl Cook Feb 06 '16 at 18:22
  • @Ali786 I cannot predict the future. Strange question. – user207421 Jul 27 '20 at 06:09
38

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Since oracle wanted everything to be oracle branded when taking over Sun, this would have been a perfect opportunity to repackage everything and get rid of this class once and for all! – Thorbjørn Ravn Andersen Mar 12 '14 at 16:10
  • 1
    @ThorbjørnRavnAndersen They did something better; they [added a Base64 class into `java.util`](http://stackoverflow.com/a/28628476/589259). – Maarten Bodewes Feb 20 '15 at 12:11
24

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.

StaticBR
  • 1,019
  • 1
  • 11
  • 25
  • 1
    Personally I don't really like that API and I would not use base 64 from an XML related class (it binds your code to an XML component that may otherwise not be required). But Oracle finally decided to implement base 64 [in the Util package in Java 8](http://stackoverflow.com/a/28628476/589259), so it's not required anymore. – Maarten Bodewes Feb 20 '15 at 12:03
7

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.

user2622016
  • 6,060
  • 3
  • 32
  • 53
  • This works because an Execution environment only exposes the Java standard API while selecting the JDK exposes all public classes, including the ones *you should not use*. – Maarten Bodewes Feb 20 '15 at 13:08
7

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.

user207421
  • 305,947
  • 44
  • 307
  • 483
PyDevSRS
  • 1,715
  • 16
  • 17
5

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);
        }
    }
}
jamshid
  • 1,775
  • 17
  • 14
  • It would be useful to document the source of speed claims like that. – avgvstvs Sep 20 '12 at 12:52
  • I think you mean javax.xml.bind.DatatypeConverter; Please correct me if I'm wrong however seeing as you gave this as an answer rather than a comment I doubt you will. – RyanfaeScotland Mar 11 '13 at 14:31
  • Sure, avgvstvs, test program and environment details added. – jamshid Mar 12 '13 at 15:25
  • Thank you for performing this analysis, but it really doesn't answer the question. You could consider creating a separate self answered question. – Maarten Bodewes Feb 20 '15 at 13:10
  • 1
    fwiw i reran this test with java 8 and the new standard java.util.Base64.getDecoder().decode("b64") is a now little faster than the previous winner, javax.xml.bind.DatatypeConverter. – jamshid Aug 16 '18 at 01:37
  • sorry! java.util.Base64.getDecoder().decode(b64) is a little slower than javax.xml.bind.DatatypeConverter. But apache codec 1.10 is ~10x slower. – jamshid Aug 16 '18 at 02:07
2
  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.

ram
  • 29
  • 1
2

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).

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
2

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

Vishwa Ratna
  • 5,567
  • 5
  • 33
  • 55
  • 2
    This could be a problem.. because i need to use BASE64Decoder (to give support to java 6 or 7) and when clients upgrade to more recent versions of JAVA, it will break the code... – marcolopes Aug 31 '20 at 22:10
2

Was getting sun.misc.base64encoder cannot be resolved to a type on eclipse -

  1. Resolved this by pointing eclipse to use Java version 1.8 installed on system - Windows -> Preferences -> Java -> Installed JREs -> add jre path (eg: C:\Program Files\Java\jdk1.8.0_271)

  2. Right-click on project -> Maven -> Update project

This will resolve then.

Apostolos
  • 10,033
  • 5
  • 24
  • 39
1

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).

NehPraka
  • 19
  • 3
0

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

Mohsin Khan
  • 90
  • 2
  • 11
0

solution: go into java 8 sdk fodler, from jre\lib\rt.jar copy to sdklib.jar (it is somewhere in eclipse folder) classes (with same paths):

sun/misc/BASE64Decoder.class,
sun/misc/BASE64Encoder.class,
sun/misc/CharacterDecoder.class,
sun/misc/CharacterEncoder.class

that's all

Maxim Akristiniy
  • 2,121
  • 2
  • 15
  • 20
-1

Add base64decoder jar and try these imports:

import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;
Fabich
  • 2,768
  • 3
  • 30
  • 44