我希望通过在用Java编写的Informix存储过程中加载资源来解决非常具体的问题。我有IFX v12和IBM Java 1.7,当我想从类路径加载任何资源(即一些属性文件)时,我已经收到IOException并显示消息"找不到资源"。
起初我认为它会对Java策略造成问题,但是当我允许所有权限时,没有任何改变。
接下来,当我能够远程调试存储过程时,我发现,该存储过程使用informix特定的类加载器informix.jvp.dbapplet.impl.JVPClassLoader。在我发现的调试中,这个类加载器没有在其类路径中的数据库中加载JAR,因此来自该JAR的资源不可用。我无法很好地调试它,因为我没有这个类加载器的可用源代码。
我有两种解决方案,但两者都很难看。我可以将JAR放在classpath中,为Informix启动Java进程,但每次我想在JAR中进行任何更改时我都必须重新启动此进程。第二种解决方案是从文件系统加载此资源,但这会使部署过程变得复杂并使其不具有抗故障性(当然还有特定的环境)。
感谢您提出任何建议,如何在classpath上提供我的JAR资源!
答案 0 :(得分:0)
好的,最后我们得到了一个解决方案,用于从Informix数据库中加载的JAR中读取属性文件。如何通过JVPClassLoader访问JAR中的属性文件是没有办法的(并且使用系统类加载器不够灵活,请参阅上面的帖子中的解决方法解决方案)。唯一的方法是从Informix系统表retain_jars读取JAR文件,并直接从JAR文件中读取属性文件。让我们看看这段Java代码:
public Properties loadPropertiesFromInformixRetainedJarsTable(final String propertyFileName) {
final Connection conn = ...;
final Statement stmt = conn.createStatement();
final ResultSet rs = stmt.executeQuery("SELECT jarname, jardata FROM retained_jars");
if (rs.next()) {
final JarInputStream jar = new JarInputStream(rs.getBinaryStream("jardata"));
JarEntry jarEntry;
while ((jarEntry = jar.getNextJarEntry()) != null) {
if (jarEntry.getName().equals(propertyFileName)) {
// read JAR entry content
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final byte[] buf = new byte[2048];
int readCnt;
// reading from JarInputStream reads from current JarEntry
while ((readCnt = jar.read(buf, 0, 2048)) != -1) {
baos.write(buf, 0, readCnt);
}
final Properties properties = new Properties();
// load properties from byte array through StringReader
properties.load(new StringReader(new String(baos.toByteArray())));
return properties;
}
}
}
// here should be of course some usual cleaning of resources (like connection, input stream ...)
}
希望对其他人有所帮助!