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)