90

I am getting an exception and I can't find the reason of it.

The exception I get is :

java.lang.IllegalAccessError: tried to access method Connected.getData(Ljava/lang/String;)Ljava/sql/ResultSet; from class B

The method is public.

public class B
{
  public void myMethod()
  {
   Connected conn = new Connected();  // create a connected class in order to connect to The DB 
   ResultSet rs = null;  // create a result set to get the query result
   rs = conn.getData(sql); // do sql query
  }
}

public class Connected 
{
 public ResultSet getData(String sql) 
{
  ResultSet rs = null;
  try 
  {
     prepareConnection();
     stmt = conn.createStatement();
     stmt.execute(sql);
     rs = stmt.getResultSet();
  }
  catch (SQLException E) 
      {
    System.out.println("Content.getData Error");
    E.printStackTrace();
       }
return rs;
}

i am using apache tomcat 5.5.12 and JAVA 1.6

Julien Kronegg
  • 4,968
  • 1
  • 47
  • 60
yossi
  • 12,945
  • 28
  • 84
  • 110

12 Answers12

123

This happens when accessing a package scoped method of a class that is in the same package but is in a different jar and classloader.

This was my source, but the link is now broken. Following is full text from google cache:

Packages (as in package access) are scoped per ClassLoader.

You state that the parent ClassLoader loads the interface and the child ClassLoader loads the implementation. This won't work because of the ClassLoader-specific nature of package scoping. The interface isn't visible to the implementation class because, even though it's the same package name, they're in different ClassLoaders.

I only skimmed the posts in this thread, but I think you've already discovered that this will work if you declare the interface to be public. It would also work to have both interface and implementation loaded by the same ClassLoader.

Really, if you expect arbitrary folks to implement the interface (which you apparently do if the implementation is being loaded by a different ClassLoader), then you should make the interface public.

The ClassLoader-scoping of package scope (which applies to accessing package methods, variables, etc.) is similar to the general ClassLoader-scoping of class names. For example, I can define two classes, both named com.foo.Bar, with entirely different implementation code if I define them in separate ClassLoaders.

Joel

s_t_e_v_e
  • 2,496
  • 3
  • 31
  • 35
  • 1
    I've got this issue on `commons-collections-3.2.1.jar` under JBoss EAP 5.3 with Struts 1.1 because this JAR is already in the JBoss libraries but was also packaged in my applications. I removed the JAR from my application which solved the problem. – Julien Kronegg May 29 '13 at 08:32
  • 3
    You just saved me A LOT of time and nerve. Very nice! – msteiger Apr 09 '15 at 07:52
  • Im getting this error for a public static method that now takes a 2nd argument. The old jar file no longer exists since I replaced it. Any ideas? – Markus Mar 17 '16 at 09:47
  • I had an abstract class with package-private modifier and another class (extending the former) with public modifier in the same package. Both were in a simple jar. I was using a method of the abstract class from a web app. The weird thing is that I was able to deploy my app in Tomcat from within Eclipse but not on Tomcat on a remote machine. I changed the access modifier of the abstract class to public and everything worked. – fabriziocucci Mar 18 '16 at 17:29
  • I my case downgrading Firefox driver from `2.53.0` to `2.44.0` helped (I used Grails 2.3.11 which is an old release). – flaz14 Jun 17 '16 at 10:53
  • +1 - tyvm. I knew it had to be something not so obvious. I've used package-scoped wrappers many times to access restricted methods. It never occurred to me that the protected class was loaded by a different class loader - sneaky developer. Thankfully, I saw your answer before I delved into a detailed debugging session. An old dog learned a new trick today :) – Frelling Dec 22 '16 at 23:55
  • More here link is broken. – somename Oct 23 '17 at 22:28
92

You are almost certainly using a different version of the class at runtime to the one you expect. In particular, the runtime class would be different to the one you've compiled against (else this would have caused a compile-time error) - has that method ever been private? Do you have old versions of the classes/jars on your system anywhere?

As the javadocs for IllegalAccessError state,

Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.

I'd definitely look at your classpath and check whether it holds any surprises.

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
  • 3
    @yossi: So how did you solve it? Recompile the soruce and put it in your classpath? Just curious if you decompiled the original class and saaw what was in it. – Victor May 10 '12 at 17:30
  • When I had this, I had saved the file with a private function made public and so the editor saw everything as okay in the .jsp file but I hadn't re-launched the main program so it hadn't actually compiled the new version. – Brian White Dec 19 '13 at 01:14
  • I'm getting this error from a maven package just installed. I've updated the project and cleaned it but anything seems to change.. – softwareplay Nov 06 '14 at 11:17
4

This happened to me when I had a class in one jar trying to access a private method in a class from another jar. I simply changed the private method to public, recompiled and deployed, and it worked ok afterwards.

Alan Smith
  • 1,069
  • 4
  • 19
  • 23
4

I was getting this error on a Spring Boot application where a @RestController ApplicationInfoResource had a nested class ApplicationInfo.

It seems the Spring Boot Dev Tools was using a different class loader.

The exception I was getting

2017-05-01 17:47:39.588 WARN 1516 --- [nio-8080-exec-9] .m.m.a.ExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.IllegalAccessError: tried to access class com.gt.web.rest.ApplicationInfo from class com.gt.web.rest.ApplicationInfoResource$$EnhancerBySpringCGLIB$$59ce500c

Solution

I moved the nested class ApplicationInfo to a separate .java file and got rid of the problem.

gtiwari333
  • 24,554
  • 15
  • 75
  • 102
  • You should also _consider to remove Spring Boot's Dev Tools from your classpath_ - maybe only temporarily. In my case the `IllegalAccessError` was not reasonable at all. But when I removed the Maven dependency to Dev Tools and added it again shortly after, everything was working as it should. – Peter Wippermann Aug 26 '19 at 13:18
  • Thank you so much! You've saved the day. – valijon Mar 16 '20 at 10:41
2

If getData is protected then try making it public. The problem could exist in JAVA 1.6 and be absent in 1.5x

I got this for your problem. Illegal access error

Kröw
  • 504
  • 2
  • 13
  • 31
Shadow
  • 6,161
  • 3
  • 20
  • 14
1

I was getting same error because of configuration issue in intellij. As shown in screenshot. Main and test module was pointing to two different JDK. (Press F12 on the intellij project to open module settings)

Also all my dto's were using @lombok.Builder which I changed it to @Data.

enter image description here

enter image description here

Vinayak Dornala
  • 1,609
  • 1
  • 21
  • 27
0

From Android perspective: Method not available in api version

I was getting this Issue primarily because i was using some thing that is not available/deprecated in that Android version

Wrong way:

Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(new Notification.Action(android.R.drawable.ic_menu_view,"PAUSE",pendingIntent));

Right way:

Notification.Builder nBuilder = new Notification.Builder(mContext);
nBuilder.addAction(android.R.drawable.ic_media_pause,"PAUSE",pendingIntent);

here Notification.Action is not available prior to API 20 and my min version was API 16

Maurice
  • 570
  • 6
  • 8
0

Just an addition to the solved answer:

This COULD be a problem with Android Studio's Instant Run feature, for example, if you realized you forgot to add the line of code: finish() to your activity after opening another one, and you already re-opened the activity you shouldn't have reopened (which the finish() solved), then you add finish() and Instant Run occurs, then the app will crash since the logic has been broken.


TL:DR;

This is not necessarily a code problem, just an Instant Run problem

Ali Bdeir
  • 4,151
  • 10
  • 57
  • 117
0

In my case the problem was that a method was defined in some Interface A as default, while its sub-class overrode it as private. Then when the method was called, the java Runtime realized it was calling a private method.

I am still puzzled as to why the compiler didn't complain about the private override..

public interface A {
     default void doStuff() {
         // doing stuff
     }
}

public class B {
     private void doStuff() {
         // do other stuff instead
     }
}

public static final main(String... args) {
    A someB = new B();
    someB.doStuff();
}
Neuron
  • 5,141
  • 5
  • 38
  • 59
0

In my case I was getting this error running my app in wildfly with the .ear deployed from eclipse. Because it was deployed from eclipse, the deployment folder did not contain an .ear file, but a folder representing it, and inside of it all the jars that would have been contained in the .ear file; like if the ear was unzipped.

So I had in on jar:

class MySuperClass {
  protected void mySuperMethod {}
}

And in another jar:

class MyExtendingClass extends MySuperClass {

  class MyChildrenClass {
    public void doSomething{
      mySuperMethod();
    }
  }
}

The solution for this was adding a new method to MyExtendingClass:

class MyExtendingClass extends MySuperClass {

  class MyChildrenClass {
    public void doSomething{
      mySuperMethod();
    }
  }

  @Override
  protected void mySuperMethod() {
    super.mySuperMethod();
  }
}
daniel sp
  • 937
  • 1
  • 11
  • 29
0

I was getting similar exception but at class level

e.g. Caused by: java.lang.IllegalAccessError: tried to access class ....

I fixed this by making my class public.

riteshk
  • 31
  • 4
0

I was getting similar exception for running junit test cases in gitlab to solve this i had to do the following changes.

Change in gitlab.yml to image: gradle:jdk8

from
image: gradle:jdk8