SunのRIをシステムクラスローダー以外から読み込む

(http://d.hatena.ne.jp/muimy/20040320#p7 のつづき)


SunのRowSet実装(RI)はシステムクラスパスに通して使う分はいいですが、
サーブレットコンテナやEclipseプラグインなどから使うと、
CachedRowSetImplなどのnew時にNullPointerExceptionになります。
(あ、サーブレットコンテナは試してないけど、たぶん)



ヌルポの元のSyncFactory#initMapIfNecessary を
見ると次のような処理を行っているようです。

String s = System.getProperty("rowset.properties");
if(s != null)
{
    ROWSET_PROPERTIES = s;
    properties.load(new FileInputStream(ROWSET_PROPERTIES));
    parseProperties(properties);
}
ROWSET_PROPERTIES = "javax" + strFileSep + "sql" + strFileSep + "rowset" + strFileSep + "rowset.properties";
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
properties.load(classloader.getResourceAsStream(ROWSET_PROPERTIES));
parseProperties(properties);

カレントスレッドのクラスローダからrowset.properties読み込んでます。
なので、rowset.jarをクラスパスに持つクラスローダーが、
カレントスレッドのクラスローダーより子にあると、
rowset.propertiesが見つからないことになります。
(普通にSyncFactory.class.getResourceAsStream(...)
してくれればいいかと思うが、、、Tigerに組み込む関係とかあるのかな?)



対処として、次のような感じで使うとエラーなく読み込めるようです。

public static CachedRowSet getCachedRowSet() throws SQLException{
    ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
    ClassLoader newLoader = MyHogeClass.class.getClassLoader();

    Thread.currentThread().setContextClassLoader(newLoader);
    CachedRowSetImpl rowset = new CachedRowSetImpl();

    Thread.currentThread().setContextClassLoader(oldLoader);
	
    return rowset;
}
//CachedRowSet rowset = new CachedRowSetImpl();
CachedRowSet rowset = getCachedRowSet();


やー、これが適切な手段か分からんけどー。

JNDI Explorer for Eclipse で似たような処理をやってたような気がする。