1. JAI(Java Advanced Imaging)をクラスパスに通して ClassLoadTest.java, Parent.java, Child.java をコンパイル。
2. JAI(Java Advanced Imaging)をクラスパスに通さないで、ClassLoadTest を実行する。

// NGバージョン
C:\>java ClassLoadTest
Couldn't load javax.media.jai.JAI.
Exception in thread "main"
 java.lang.NoClassDefFoundError: javax/media/jai/PlanarImage
 at ClassLoadTest.test(ClassLoadTest.java:18)
 at ClassLoadTest.main(ClassLoadTest.java:11)

クラス(サブクラスでは使っていないはずだけど)がロードできないという理由でエラーになったのか?

PlanarImage pi = null; // ← 宣言がいけないのか?
と思って、サブクラスからは利用していない
親クラスの private メソッド useJAI() 内で、
宣言しないでメソッドチェーンするように修正したら、問題なく動くようになった。(なんで?)

// OKバージョン
C:\>java ClassLoadTest
Couldn't load javax.media.jai.JAI.
Child#method
Child#unuseJAI

しかし、何気なく
戻り値の BufferedImage を void に変えて、
それらしく修正しても、OKになってしまった。

お手上げ。でも、とりあえずここにメモ。
# 問題は解決したが理由がわからないので怖い。

ClassLoadTest.java

public class ClassLoadTest {
 
  public static void main(String[] args) {
 
    if(isExistClass("javax.media.jai.JAI")){
      System.out.println("Could load javax.media.jai.JAI.");
    }else{
      System.out.println("Couldn't load javax.media.jai.JAI.");
    }
 
    new ClassLoadTest().test();
 
  }
 
  private Parent p;
 
  public void test(){
    p = new Child();
    p.method();
  }
 
  public static boolean isExistClass(String name) {
    try {
      Class.forName(name);
    } catch (Exception e) {
      boolean flag = false;
      return flag;
    }
    return true;
  }
 
}

Parent.java

import java.awt.image.BufferedImage;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
 
public class Parent {
 
  public Parent() {
    super();
  }
 
  public void method() {
    System.out.println("Parent#method");
    useJAI();
  }
 
  private BufferedImage useJAI() {
    System.out.println("Parent#useJAI");
 
    // NGバージョン
    //PlanarImage pi = null;
    //pi = JAI.create("", "");
    //return pi.getAsBufferedImage();
 
    // OKバージョン
    return JAI.create("", "").getAsBufferedImage();
  }
 
  // 実は、これでもOK.
  // 戻り値にも左右される?
  //private void useJAI() {
  //  System.out.println("Parent#useJAI");
  //  PlanarImage pi = null;
  //  pi = JAI.create("", "");
  //  pi.getAsBufferedImage();
  //}
 
}

Child.java

public class Child extends Parent {
 
  public Child(){
    super();
  }
 
  public void method() {
    System.out.println("Child#method");
    unuseJAI();
  }
 
  private void unuseJAI() {
    System.out.println("Child#unuseJAI");
  }
 
}

tags: Java zurazure

Posted by NI-Lab. (@nilab)