development

java.lang.IllegalAccessError : 메소드에 액세스하려고했습니다.

big-blog 2020. 11. 6. 21:03
반응형

java.lang.IllegalAccessError : 메소드에 액세스하려고했습니다.


예외가 발생하는데 그 이유를 찾을 수 없습니다.

내가 얻는 예외는 다음과 같습니다.

java.lang.IllegalAccessError : Connected.getData (Ljava / lang / String;) Ljava / sql / ResultSet 메소드에 액세스하려고했습니다. 클래스 B에서

방법은 공개입니다.

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;
}

아파치 바람둥이 5.5.12 및 JAVA 1.6을 사용하고 있습니다.


런타임에 예상 한 것과 다른 버전의 클래스를 거의 확실히 사용하고 있습니다. 그 방법은있다 - 특히, 런타임 클래스는이에 대해 컴파일 한 (다른 사람이 컴파일 타임 오류가 발생하는 것)하는 것과 다른 것 이제까지 있었다 private? 시스템에 이전 버전의 클래스 / jar이 있습니까?

IllegalAccessError상태에 대한 javadocs로서 ,

일반적으로이 오류는 컴파일러에 의해 포착됩니다. 이 오류는 클래스 정의가 비호 환적으로 변경된 경우에만 런타임에 발생할 수 있습니다.

나는 확실히 당신의 클래스 경로를보고 그것이 놀라움을 가지고 있는지 확인합니다.


이것은 동일한 패키지에 있지만 다른 jar 및 클래스 로더에있는 클래스의 패키지 범위 메소드에 액세스 할 때 발생합니다.

이것은 내 소스 였지만 이제 링크가 끊어졌습니다. 다음은 Google 캐시의 전체 텍스트입니다.

패키지 (패키지 액세스에서와 같이)는 ClassLoader별로 범위가 지정됩니다.

부모 ClassLoader가 인터페이스를로드하고 자식 ClassLoader가 구현을로드한다고 명시합니다. 이것은 패키지 범위 지정의 ClassLoader 특정 특성 때문에 작동하지 않습니다. 인터페이스는 동일한 패키지 이름이지만 다른 ClassLoader에 있기 때문에 구현 클래스에 표시되지 않습니다.

이 스레드의 게시물을 훑어 보았지만 인터페이스를 공개로 선언하면 이것이 작동한다는 것을 이미 발견했다고 생각합니다. 또한 인터페이스와 구현이 동일한 ClassLoader에 의해로드되도록 작동합니다.

실제로 임의의 사람들이 인터페이스를 구현할 것으로 예상하면 (구현이 다른 ClassLoader에 의해로드되는 경우 분명히 수행하는 작업) 인터페이스를 공개해야합니다.

패키지 범위의 ClassLoader 범위 (패키지 메서드, 변수 등에 액세스하는 데 적용됨)는 클래스 이름의 일반 ClassLoader 범위와 유사합니다. 예를 들어, 별도의 ClassLoaders에서 정의하는 경우 완전히 다른 구현 코드로 com.foo.Bar라는 이름의 두 클래스를 정의 할 수 있습니다.

조엘


getData보호되는 경우 공개로 설정하십시오. JAVA 1.6에는 문제가있을 수 있으며 1.5x에는 없을 수 있습니다.

나는 당신의 문제로 이것을 얻었습니다. 불법 액세스 오류


이것은 한 병에 클래스가 다른 병에서 클래스의 개인 메서드에 액세스하려고 할 때 발생했습니다. 나는 단순히 private 메서드를 public으로 변경하고 다시 컴파일하고 배포 한 후 정상적으로 작동했습니다.


@RestController ApplicationInfoResource중첩 된 클래스가있는 Spring Boot 애플리케이션에서이 오류가 발생했습니다 ApplicationInfo.

Spring Boot Dev Tools다른 클래스 로더를 사용하고있는 것 같습니다 .

내가 얻은 예외

2017-05-01 17 : 47 : 39.588 WARN 1516 --- [nio-8080-exec-9] .mmaExceptionHandlerExceptionResolver : 핸들러 실행으로 인한 예외 해결 : org.springframework.web.util.NestedServletException : 핸들러 디스패치 실패; 중첩 된 예외는 java.lang.IllegalAccessError : com.gt.web.rest.ApplicationInfoResource $$ EnhancerBySpringCGLIB $$ 59ce500c 클래스에서 com.gt.web.rest.ApplicationInfo 클래스에 액세스하려고했습니다.

해결책

중첩 된 클래스 ApplicationInfo를 별도의 .java 파일 로 이동 하고 문제를 제거했습니다.


Android 관점에서 : API 버전에서 사용할 수없는 메서드

이 문제는 주로 해당 Android 버전에서 사용할 수 없거나 더 이상 사용되지 않는 것을 사용했기 때문에 발생했습니다.

잘못된 방법:

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

올바른 방법 :

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


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


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();
}

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();
  }
}

참고URL : https://stackoverflow.com/questions/7076414/java-lang-illegalaccesserror-tried-to-access-method

반응형