可能吗? 1) 使用 ojdbc5 或 ojdbc6 连接到 Oracle 8i 2) 多个 ojdbc jar

发布于 2024-09-26 01:22:55 字数 985 浏览 7 评论 0原文

我正在构建一个应用程序,该应用程序整理来自多个数据源的数据。在这些数据源中,我们有多个正在运行的 Oracle 实例。

我发现连接到 Oracle 8i 实例的唯一方法是使用 ojdbc14.jar 和以下内容:

String driver = "oracle.jdbc.OracleDriver";
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=$HOST)(PORT=$PORT)))(CONNECT_DATA=(SID=$SID)))"
Class.forName(driver);
Connection c = DriverManager.getConnection(url, $USER, $PASSWORD);
c.close();

当我尝试更新到 ojdbc5.jar 或 < em>ojdbc6.jar,使用相同的代码,我得到一个 ArrayIndexOutofBoundsException。如果我只使用 URL“jdbc:oracle:thin:$user/$password@$host:$port:$sid”,情况也是如此,它确实适用于我连接到的最新 Oracle 实例。

我不想被迫使用旧的 ojdbc14.jar(特别是当我使用 Java 6 时),因为我可能很快就必须支持更高的 Oracle 数据库。

所以,我希望以下两种情况之一是可能的:

1)有一个连接字符串我只是忽略了它可以用来连接到 Oracle 8i w/更新的 OJDBC jar。

2) 我的类路径上可以有多个 OJDBC jar,这样我就可以在异常情况下使用 ojdbc14.jar,并在其他地方使用 ojdbc6.jar。当然,这里的技巧是弄清楚如何指定连接需要使用哪个 jar 中的“oracle.jdbc.OracleDriver”类。

有什么想法吗?

I'm building an application which is collating data from multiple data sources. Of these data sources, we have multiple instances of Oracle running.

I find that the only way I can connect to my Oracle 8i instance is by using the ojdbc14.jar and the following:

String driver = "oracle.jdbc.OracleDriver";
String url = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=$HOST)(PORT=$PORT)))(CONNECT_DATA=(SID=$SID)))"
Class.forName(driver);
Connection c = DriverManager.getConnection(url, $USER, $PASSWORD);
c.close();

When I try to update to ojdbc5.jar or ojdbc6.jar, using the same code, I get an ArrayIndexOutofBoundsException. Ditto if I use just the URL "jdbc:oracle:thin:$user/$password@$host:$port:$sid", which does work against the more recent Oracle instances I'm connecting to.

I'd rather not get locked into having to use the older ojdbc14.jar (especially as I'm using Java 6) as I might have to support higher Oracle databases quite soon in the future.

So, I'm hoping one of two scenarios is possible:

1) There's a connection string I'm simply overlooking which can use to connect to Oracle 8i w/ more recent OJDBC jars.

2) I can have multiple OJDBC jars on my classpath so that I can use ojdbc14.jar on an exception basis and ojdbc6.jar everywhere else. The trick here, of course, is figuring out how to specify which jar the connection needs to use the "oracle.jdbc.OracleDriver" class from.

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

椒妓 2024-10-03 01:22:55

出于好奇,我通过隔离的类加载器实现了您的第二种方法。它似乎工作:

public class DriverWrapper implements Driver {
    private Driver target;
    private String fakePrefix;
    private String realPrefix;

    protected DriverWrapper(Driver target, String  fakePrefix, String realPrefix) {
        this.target = target;
        this.fakePrefix = fakePrefix;
        this.realPrefix = realPrefix;
    }

    public static void loadDriver(URL[] classPath, String className, String fakePrefix, String actualPrefix) 
        throws Exception{

        URLClassLoader cl = new URLClassLoader(classPath, DriverWrapper.class.getClassLoader());
        Class<?> c = cl.loadClass(className);        

        // It's rather rude, but we haven't access to the existing instance anyway
        Driver d = (Driver) c.newInstance();
        Driver w = new DriverWrapper(d, fakePrefix, actualPrefix);

        // We don't care about already registerd instance, 
        // because driver loaded in isolated classloader 
        // is not visible to the rest of application, see DriverManager javadoc
        DriverManager.registerDriver(w);
    }

    private String resolveURL(String url) {
        if (url.startsWith(fakePrefix)) {
            return realPrefix + url.substring(fakePrefix.length());
        } else {
            return null;
        }
    }

    public boolean acceptsURL(String url) throws SQLException {
        url = resolveURL(url);
        if (url == null) {
            return false;
        } else {
            return target.acceptsURL(url);
        }
    }

    public Connection connect(String url, Properties info) throws SQLException  {
        url = resolveURL(url);
        if (url == null) {
            return null;
        } else {
            return target.connect(url, info);
        }
    }

    public int getMajorVersion() {
        return target.getMajorVersion();
    }

    public int getMinorVersion() {
        return target.getMinorVersion();
    }

    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException  {
        return target.getPropertyInfo(url, info);
    }

    public boolean jdbcCompliant() {
        return target.jdbcCompliant();
    }

}

使用如下(驱动程序 jar 不应位于主类路径中):

DriverWrapper.loadDriver(new URL[] { new File("ojdbc5.jar").toURL() }, 
    "oracle.jdbc.OracleDriver", "jdbc:oracle5", "jdbc:oracle");   
DriverWrapper.loadDriver(new URL[] { new File("ojdbc14.jar").toURL() }, 
    "oracle.jdbc.OracleDriver", "jdbc:oracle14", "jdbc:oracle");

... DriverManager.getConnection("jdbc:oracle14:...", ...);
... DriverManager.getConnection("jdbc:oracle5:...", ...);

Just out of curiosity I implemented your second approach via isolated classloader. It seems to be working:

public class DriverWrapper implements Driver {
    private Driver target;
    private String fakePrefix;
    private String realPrefix;

    protected DriverWrapper(Driver target, String  fakePrefix, String realPrefix) {
        this.target = target;
        this.fakePrefix = fakePrefix;
        this.realPrefix = realPrefix;
    }

    public static void loadDriver(URL[] classPath, String className, String fakePrefix, String actualPrefix) 
        throws Exception{

        URLClassLoader cl = new URLClassLoader(classPath, DriverWrapper.class.getClassLoader());
        Class<?> c = cl.loadClass(className);        

        // It's rather rude, but we haven't access to the existing instance anyway
        Driver d = (Driver) c.newInstance();
        Driver w = new DriverWrapper(d, fakePrefix, actualPrefix);

        // We don't care about already registerd instance, 
        // because driver loaded in isolated classloader 
        // is not visible to the rest of application, see DriverManager javadoc
        DriverManager.registerDriver(w);
    }

    private String resolveURL(String url) {
        if (url.startsWith(fakePrefix)) {
            return realPrefix + url.substring(fakePrefix.length());
        } else {
            return null;
        }
    }

    public boolean acceptsURL(String url) throws SQLException {
        url = resolveURL(url);
        if (url == null) {
            return false;
        } else {
            return target.acceptsURL(url);
        }
    }

    public Connection connect(String url, Properties info) throws SQLException  {
        url = resolveURL(url);
        if (url == null) {
            return null;
        } else {
            return target.connect(url, info);
        }
    }

    public int getMajorVersion() {
        return target.getMajorVersion();
    }

    public int getMinorVersion() {
        return target.getMinorVersion();
    }

    public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException  {
        return target.getPropertyInfo(url, info);
    }

    public boolean jdbcCompliant() {
        return target.jdbcCompliant();
    }

}

Used as follows (driver jars shouldn't be located in the main classpath):

DriverWrapper.loadDriver(new URL[] { new File("ojdbc5.jar").toURL() }, 
    "oracle.jdbc.OracleDriver", "jdbc:oracle5", "jdbc:oracle");   
DriverWrapper.loadDriver(new URL[] { new File("ojdbc14.jar").toURL() }, 
    "oracle.jdbc.OracleDriver", "jdbc:oracle14", "jdbc:oracle");

... DriverManager.getConnection("jdbc:oracle14:...", ...);
... DriverManager.getConnection("jdbc:oracle5:...", ...);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文