6

Learning Java. I have two files, each containing one java class. When I run the file with the main method, I get the following error:

Exception in thread "main" java.lang.IllegalAccessError: failed to access class TapeDeck from class TapeDeckTestDrive (TapeDeck is in unnamed module of loader 'app'; TapeDeckTestDrive is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader @18bf3d14) at TapeDeckTestDrive.main(TapeDeckTestDrive.java:3)

class TapeDeckTestDrive{
  public static void main(String[] args){
    TapeDeck t = new TapeDeck();
    t.canRecord = true;
    t.playTape();

    if (t.canRecord == true) {
        t.recordTape();
    }
  }
}
class TapeDeck {
  boolean canRecord = false;
  void playTape(){

    System.out.println("tape playing");
  }
  void recordTape(){

    System.out.println("tape recording");
  }
}

Any help please?

Abdul Hussain
  • 182
  • 2
  • 2
  • 11
  • Are you using command prompt or any IDE to run your code? – Jeet Kumar Apr 22 '19 at 14:29
  • The error message complains about class `TapeDeckcTestDrive`. How are you running your code? Did you mistyped it? The code you have posted has no errors, as far as I can tell. – whbogado Apr 22 '19 at 14:50
  • 1
    Do you have those classes in the same package? if not, you have to set the 'public' all your methods and variables...check this tutorial from oracle...https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html – tommybee Apr 22 '19 at 15:03
  • @JeetKumar I have tried both IntelliJIdea and command promtp (I created 2 sets of .java files so they don't access the same files) – Abdul Hussain Apr 23 '19 at 13:24
  • @tommybee I added public to classes/methods and boolean. Now the initial error is gone but the error is now at accessing the method. See below: **_Exception in thread "main" java.lang.IllegalAccessError: class TapeDeckTestDrive tried to access method TestDrive.playTape()V (TapeDeckTestDrive is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader @18bf3d14; TestDrive is in unnamed module of loader 'app') at TapeDeckTestDrive.main(TDTestDrive.java:5)_** – Abdul Hussain Apr 23 '19 at 13:26
  • OK never mind. It works now :) adding public to all methods did the trick. – Abdul Hussain Apr 23 '19 at 13:38
  • @Abdul Hussain, What will happen if you change your package path of the TapeDeck class then call it with full package name? for example a.b.TapeDeck t = new a.b.TapeDeck(); assume that a.b is your current package. – tommybee Apr 23 '19 at 13:53
  • @tommybee it works! I had to learn what you meant in the comment but the package path (after I create a directory using javac -d . .java) works. – Abdul Hussain Apr 24 '19 at 13:27
  • I don't know the proper protocol on near-duplicates on SO, short of proposing to close them, which I haven't. However, I'd like to point out that there's a question with the same exact error [here](https://stackoverflow.com/questions/61000231/exception-in-thread-main-java-lang-illegalaccesserror-failed-to-access-class/61527715#61527715). For that reason, I've pasted the same response, just with a different "OP Specific" note at the bottom. Just for the others who come across this page with the same error! – AviFS Apr 30 '20 at 16:20

4 Answers4

13

Actual Issue

I got this exact same error* doing something very silly:

I tried to run the file as java {main-class}.java. That simple!

Instead, be sure to run it simply as java {main-class}.


*Specifically, the error format I had, like yours:

Exception in thread "main" java.lang.IllegalAccessError: failed to access class {pack.other-class} from class {pack.main-class} ({pack.other-class} is in unnamed module of loader 'app'; {pack.main-class} is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader @29f69090)

  at {pack.main-class}.{who-cares-where}
  at {pack.main-class}.{who-cares-why}
             . . .


Extra Advice

You can get a similarly annoying error on the same issue, namely inability to access packages in the same directory, if you only compile your {main-class}.

So instead of javac {directory}/{main-class}.java

Be sure to compile all of them at the same time, so there's no issue in cross-referencing:
  javac {directory}/*.java


OP Specific

This would just be a silly command-line mistake. If it's occurring in IntelliJ as well, as you say, this isn't your issue. However, I hope it's at least helpful to the others who come across your question with this error!

AviFS
  • 336
  • 2
  • 12
3

Quick possible fix, try making the classes and methods "Public".

Under normal circumstances this shouldn't be necessary but you may be hitting a specific case where it might be (It's an edge case so I don't know if it's a problem or not off the top of my head):

Java is really uncomfortable with stuff being in the "Default" package--code from other packages can't access objects in the default package (Meaning no package statement). Although this shouldn't cause problems in your case, maybe your "package" level security settings are also not working in the default package.

If this is actually the problem, the two fixes would be to make the packages and methods public (as I said above) or move both classes into a package.

Bill K
  • 62,186
  • 18
  • 105
  • 157
2

Make sure each class is in the same folder, since the error is saying TapeDeckTestDrive can not find TapeDeck. I would recommend starting out with an IDE like Eclipse since it will help you focus more on coding and less with folder problems.

I know your code is all good (in java 8 at least) since when I copied it in eclipse it works no problem, meaning it has to be a folder problem, a problem with the installed version of java, or the way you are running the code is not working for some reason. If both files are in the exact same folder then I would make sure your java version says 1.8 something in the system files (Program Files(x86) most likely in windows), if it does not say that version then it could be another problem with the code and syntax for that version. Another thing that might help is to put public behind the "class" on the first line of each class and make the Boolean public. This might be a syntax requirement on other versions of java or something that is needed when running off command prompt.

JavaPerson
  • 36
  • 2
  • 1) Added public to classes/methods/boolean. Now the error is with accessing tapedeck.playTape(), but the initial error is no more. **_Exception in thread "main" java.lang.IllegalAccessError: class TapeDeckTestDrive tried to access method TestDrive.playTape()V (TapeDeckTestDrive is in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader @18bf3d14; TestDrive is in unnamed module of loader 'app') at TapeDeckTestDrive.main(TDTestDrive.java:5)_** 2) I have JDK12.0.1 3) I have run the code on the terminal in IntelliJIdea as well as command prompt. Identical errors. – Abdul Hussain Apr 23 '19 at 13:21
  • Both files are in the same folder. – Abdul Hussain Apr 23 '19 at 13:23
  • Ok never mind. It works now. Adding public to all methods did the trick! – Abdul Hussain Apr 23 '19 at 13:38
0

What worked for me was to add the key word 'public' in both methods (playTape and recordPlay) and variables (canRecord).

Ramon Orraca
  • 31
  • 1
  • 4