iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >克服J2SE 1.3 ~ 1.4不兼容问题 (转)
  • 630
分享到

克服J2SE 1.3 ~ 1.4不兼容问题 (转)

2023-06-03 03:06:28 630人浏览 安东尼
摘要

克服J2SE 1.3 ~ 1.4不兼容问题 (转)[@more@]克服j2se 1.3 ~ 1.4不兼容问题--从反射api和ANT获得帮助 概要  如果你要实现Javaapi中的一个,那么可能是件比较痛苦的事情。你经常会需要实现

克服J2SE 1.3 ~ 1.4不兼容问题 (转)[@more@]

克服j2se 1.3 ~ 1.4不兼容问题
--从反射api和ANT获得帮助



概要
  如果你要实现Javaapi中的一个,那么可能是件比较痛苦的事情。你经常会需要实现许多交叉依赖的接口。对新特性的需求促成了升级现有的JavaAPI,这就造成了提供这些API的供应商对他们的相关实现不断的升级以维持相关功能。随着这些API的升级更改越来越频繁,API代码的不兼容使你不得不分别维护新旧版本的代码库。这直接到导致了你维护成本和难度的增加。本文演示了解决此问题的技术,揭示了如何仅使用一个代码库编译不同JavaAPI版本的代码。



  现在非常多的API被加入到到Java的标准库中,比如JdbC。这样做的好处是,Java可选包在部署时不必被绑定到相关的部署应用中去。这些API由专门的专业开发小组实现,在实际的使用当中这些API变得越来越受欢迎,使用的深度及广度也在不断的增加。但是有时候对一些API升级会变得使一些类及方法不可用。开发小组宁愿让这些API包成为可选组件而不是作为Java标准支持库的形式来发布。但是一旦加入标准库中的API包,就像是和用户签定了终生契约,想再成为可选包是不可能的。所以作为用户的你,可能会突然发现你一下子自己的代码库变成了不兼容的2个代码库,一个是使用新API的代码库,另一个是使用旧API的代码库。你可能会以为情况不像你想象的那样糟糕。我这里举一个简单的例子。J2SE1.4中由于对JDBC中的一些API的升级使的java.sql.Connection 不能同时被1.3 及 1.4 版本编译通过。你可能会遇到我这样的困境:我可能需要实现java.sql.Connection这个接口,但是我的代码需要同时通过1.3 及1.4 得编译。但是我不想同时维护2个版本的代码库。所以我开始寻找更好的解决方法。
  如果你依赖于javac来编译你的应用的话,那么很不幸,Java著名的一次编写,到处运行(WORA)并不包括WOCA(一次编写,到处编译^_^;)。
不过别太沮丧,编码的反射技巧以及编译的Ant技巧是你能够安然过关。我能够仅仅使用一组Java文件以及Ant工具,就能使一个版本同时编译
在1.3 和1.4 版本下面。别急,在我结识解决办法之前,让我先详细的解释一下问题的描述。

可怜人的连接池(PS:Poor man's connection pool ,很有意思的一句话)
  两年前,我的公司需要一个连接池,但是又不肯出钱买一个。当时并没有什么免费的东东可以使用,所以我们自己写了一个连接池。为了能更好的跟踪在整个应用中连接的情况,我们写了一个com.icentris.sql.ConnectionWrapper类,它实现了java.sql.Connection 接口以及其他的一些包装类(实现了另外的一些的java.sql 接口)。这些包装类仅仅是跟踪我们应用中的数据库使用,以及通过方法调用真正的
数据库资源。
  当J2SE1.4来的时候,我们自然而然的想到升级我们提供给客户的应用,使这些应用的性能得到很多提升。当然,我们也需要保留1.3版本,因为有些客户根本不需要升级到1.4。我们气恼的发现,如果我们不修改,我们的ConnectionWrapper 以及其他JDBC封装类根本通不过J2SE1.4的编译。
  为了文章的简明,我通过使用ConnectionWrapper 这个类来演示我对所有其他不能够通过J2SE1.4的类所使用的技术。如果我按照新的API标准,那么我不得不添加几个方法到ConnectionWrapper中去,接下来2个大问题摆在了面前:
1.因为我的包装类需要经历方法调用,我将不得不调用在J2SE1.3 sql类中并不存在的方法。
2.因为一些新的方法涉及到一些新出现的类,我将不得不在编译中面对那些在J2SE1.3中并不存在的类。

反射提供了援助
一些代码可以很方便的解释第一个问题。但是我的ConnectionWrapper 封装了java.sql.Connection , 所有的我的例子
依赖于在构造方法中的变量 realConnection :

private java.sql.Connection realConnection = null;
 
  public ConnectionWrapper(java.sql.Connection connection) {
  realConnection = connection;
  }

  为了看清楚我怎么做到解决版本不兼容问题,让我们仔细看一下setHoldability(int)(这个在J2SE1.4被声明的新方法)
public void setHoldability(int holdability) throws SQLException {
  realConnection.setHoldability( holdability );
  }

  很不幸,这个方法在J2SE1.3中显然通不过编译,这就陷入了2难的尴尬境地。为了解决这一情况,我假定setHoldability() 将只会在J2SE1.4
下面被调用,所以我使用了反射机制来调用该方法。

public void setHoldability(int holdability) throws SQLException {
  Class[] argTypes = new Class[] { Integer.TYPE };
  object[] args = new Object[] {new Integer(holdability)};
  callJava14Method("setHoldability", realConnection, argTypes, args);
  }

  public static Object callJava14Method(String methodName, Object instance,
  Class[] argTypes, Object[] args)
  throws SQLException
  {
  try {
  Method method = instance.getClass().getMethod(methodName, argTypes);
  return method.invoke(instance, args );
  } catch (NoSuchMethodException e) {
  e.printStackTrace();
  throw new SQLException("Error Invoking method (" + methodName + "): "
  + e);
  } catch (IllegalAccessException e) {
  e.printStackTrace();
  throw new SQLException("Error Invoking method (" + methodName + "): "
  + e);
  } catch (InvocationTargetException e) {
  e.printStackTrace();
  throw new SQLException("Error Invoking method (" + methodName + "): "
  + e);
  }
  }

  现在我有了setHoldability() 方法,因此能顺利通过J2SE1.4的编译。原理是我并不直接调用J2SE1.3中间java.sql.Connection并不存在的方法,
而是转为通过让setHoldability调用callJava14Method这个通用方法来调用,然后在一个SQLException 里封装所有的异常。这样就达到我预期的效果。
现在所有的在J2SE1.4中新方法都工作的很好,在J2SE1.3的老版本下也能顺利编译而且工作正常。现在我来着手解决第二个问题。
就是如何在应用中能够找到一个方法能够使用J2SE1.3中并不存在的新的类。

Ant 是答案
在J2SE1.4中,java.sql.Connection 依赖于一个新的类java.sql.Savepoint。因为这个类在java.sql 包中,所以你不可能把它加入到J2SE1.3中去。Java不允许任何的第三方扩展包加入它的核心包(java.* 以及 javax.* )中去。 因此挑战来了,在J2SE1.4下调用这个新的java.sql.Savepoint 类,但同时需要代码能够在J2SE1.3下面得到编译以及能够运行。很简单,不是吗?所有回答"Yes"的人都会得到一个榛仁巧克力饼(PS:哈哈,我回答了,可是没有:P)。至少现在我找到了答案,使问题变得很简单了。
  首先我插入了下面一条有条件的import语句
// Comment_next_line_to_compile_with_Java_1.3
  import java.sql.Savepoint;

  然后我找到了一个能够在J2SE1.3下面注释掉import的方法。非常简单,使用如下Ant 语句就可以了:

  Comment_next_line_for_Java_1.3
  Comment_next_line_for_Java_1.3 //
 

  这个Ant 的 replace 标签 有好几个标签选项,在以后我给出的全部例子里有很多。在这里面最重要的是使用来替换 。 在XML里面的意思是换行。在J2SE1.4下,没什么会发生, 但是在J2SE1.3下面一个import声明被注释掉了。
// Comment_next_line_to_compile_with_Java_1.3
  //import java.sql.Savepoint;

  但是我在代码中Savepoint仍在使用public Savepoint setSavepoint(String name) throws SQLException { . . .}。不过我只在J2SE1.4使用这些方法类,在J2SE1.3中只要能编译就可以了。我发现只要我有一个我自己的Savepoint 类在我的包中,我的代码就能够通过编译,而且不用任何的import包。但是我又要同时在这条import 语句不被注释的同时我自己的Savepoint类被忽略掉。因此我造了一个空的com.icentris.sql.Savepoint类,这个可能(除了JavaDoc)是最短的有效类:
package com.icentris.sql;

 
  public class Savepoint {}

  在J2SE1.4下我能够正确的import java.sql.Savepoint类,而在J2SE1.3下面Ant注释了这条import语句。因此这个Savepoint就被替换成了我这个包里面写的一个空的Savepoint类。所以我现在就能加入任何引用到Savepoint类的方法,同样的在这些新方法中使用刚才所说的反射方法。
// Comment_next_line_to_compile_with_Java_1.3
  import java.sql.Savepoint;

  . . .
  public Savepoint setSavepoint() throws SQLException {
  Class[] argTypes = new Class[0];
  Object[] args = new Object[0];
  return (Savepoint) callJava14Method("setSavepoint", realConnection,
  argTypes, args);
  }

  public Savepoint setSavepoint(String name) throws SQLException {
  Class[] argTypes = new Class[] { String.class };
  Object[] args = new Object[] { name };
  return (Savepoint) callJava14Method("setSavepoint", realConnection,
  argTypes, args);
  }

  public void rollback(Savepoint savepoint) throws SQLException {
  Class[] argTypes = new Class[] { Savepoint.class };
  Object[] args = new Object[] { savepoint };
  callJava14Method("rollback", realConnection, argTypes, args);
  }

  public void releaseSavepoint(Savepoint savepoint) throws SQLException {
  Class[] argTypes = new Class[] { Savepoint.class };
  Object[] args = new Object[] { savepoint };
  callJava14Method("releaseSavepoint", realConnection, argTypes, args);
  }

  现在我所要做的就是能够使Ant 识别 J2SE1.3版,然后能够使这条import 语句被注释掉。

 
 
 
 
 
 
 

 

 

 
 

    name="isJava13">
 
 
 
 

 

    name="doJava13Tweaks" depends="isJava13" if="isJava13">
 
 
 
  Comment_next_line_for_Java_1.3
  Comment_next_line_for_Java_1.3 //
 

 

 
 
 
  Comment_next_line_for_Java_1.3 //
  Comment_next_line_for_Java_1.3
 

 

  注意编译目标在调用doJava13Tweaks的前后都调用了undoJava13Tweaks。如果万一javac编译失败的话,我们可以恢复以前的编译版本。

你没有必要同时维护2个应用实现
  对于Java来说,新的API升级所带来的新的方法以及新的类/接口并不是新鲜事。一般而言,加入的新方法以及新的类的同时,会考虑到向上兼容的问题来照顾老API用户。但是当升级的API属于Java核心包内时,就会很麻烦。因为Java不允许对这些核心包的任何的外在更改或者是增加。通常这会引起针对不同版本API而维护不同版本代码树的需要。但是,就像上面的例子所演示的那样,你只要维护一棵代码树就能够在不同的版本的API下,编译运行。这个反射的API允许你调用并不存在的方法,而Ant能通过识别不同的Java编译版本而对相应的import包进行调整。虽然上面的所举的例子仅仅是一个简单的演示,但是在实际工作当中,利用这些简单的技术,解决了许多J2SE1.4和J2SE1.3的版本问题。我相信通过这些技术,你可以在频繁的Java版本升级中不必为同时维护两棵代码库而烦恼。


关于作者:
Sam Mefford是iCentris的首席架构设计师。对于系统的兼容性重视程度,Sam Mefford是放在第一位的。他带领的团队致力于使用一个代码库
向众多的客户公司提供应用发布方案。这些部署方案使用的应用服务器TomcatWEBLOGIC, Resin, Orion以及 websphere;在数据库方面有
oracle,postgresql, MYSQL,以及 InfORMix;以及多个Java运行期环境。

译者: SpikeWang (CSDN ID:hk2000c)

东华大学计算机系毕业,现在同济大学攻读软件工程硕士学位。致力于J2EE方面的企业级应用开发以及研究工作。


About Copyright:
原文章版权属于作者 Sam Mefford
译文版权属于译者及原文作者共同所有,欢迎转载,但要注上译者及原文作者。


参考资源:
The API for java.sql.Connection (J2SE 1.3):
Http://java.sun.com/j2se/1.3/docs/api/java/sql/Connection.html

The API for java.sql.Connection (J2SE 1.4):
http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Connection.html

The JDBC API:
http://java.sun.com/products/jdbc/

Java Core Reflection参考概要:
ide/reflection/spec/java-reflectionTOC.doc.html">http://java.sun.com/j2se/1.3/docs/guide/reflection/spec/java-reflectionTOC.doc.html

the Reflection API指南:
http://java.sun.com/docs/books/tutorial/reflect/

The Javadoc (java.lang.reflect):
http://java.sun.com/j2se/1.3/docs/api/java/lang/reflect/package-summary.html


--结束END--

本文标题: 克服J2SE 1.3 ~ 1.4不兼容问题 (转)

本文链接: https://www.lsjlt.com/news/232374.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 克服J2SE 1.3 ~ 1.4不兼容问题 (转)
    克服J2SE 1.3 ~ 1.4不兼容问题 (转)[@more@]克服j2se 1.3 ~ 1.4不兼容问题--从反射api和ANT获得帮助 概要  如果你要实现JavaAPI中的一个,那么可能是件比较痛苦的事情。你经常会需要实现...
    99+
    2023-06-03
  • 解决padding ie不兼容问题
    这篇文章主要讲解了“解决padding ie不兼容问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“解决padding ie不兼容问题”吧!通常我们遇到3种...
    99+
    2024-04-02
  • 关于cuda和pytorch不兼容问题
    关于cuda和pytorch不兼容问题 问题描述 之前是按照网上教程安装的Cuda和pytorch,使用了一段时间之后,在一项任务中安装fastai时,出现了两者版本不兼容问题,无法运行。 找不到指定...
    99+
    2023-09-10
    pytorch python 深度学习
  • win10不兼容问题如何解决
    解决Windows 10不兼容问题可以尝试以下方法:1. 更新驱动程序:访问电脑制造商的官方网站或设备制造商的网站,下载并安装最新的...
    99+
    2023-10-09
    win10
  • JPA与mybatis-plus不兼容问题的解决
    引入mybatis-plus后,在spring-boot启动时,JPA会使用CCJSqlParser对SQL进行分析处理,由于@Query中的Native-SQL语法并非完全的sql...
    99+
    2023-02-24
    JPA与mybatis-plus不兼容 Mybatis Plus JPA 冲突
  • JPA与mybatisplus不兼容问题如何解决
    这篇文章主要介绍了JPA与mybatisplus不兼容问题如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JPA与mybatisplus不兼容问题如何解决文章都会有所收获,下面我们一起来看看吧。引入myb...
    99+
    2023-07-05
  • HTML与IE浏览器不兼容的问题
    HTML是一种Web页面标记语言,它被广泛应用于Web开发中。然而,HTML页面在不同浏览器中的表现却大不相同,特别是在IE浏览器中,HTML页面通常会出现各种兼容性问题,导致网页无法正常显示和使用。下面将介绍HTML与IE浏览器不兼容的问...
    99+
    2023-05-14
  • 如何解决IE8下不兼容rgba()的问题
    这篇文章主要介绍如何解决IE8下不兼容rgba()的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!rgba()是css3的新属性,所以IE8及以下浏览器不兼容,这怎么办呢?终于我...
    99+
    2024-04-02
  • 解决云服务器装虚拟机不兼容的问题
    1. 确认虚拟机兼容性 在安装虚拟机之前,首先需要确认云服务器的硬件和操作系统是否支持虚拟化技术。不同的云服务器提供商和型号可能有不同的兼容性要求,因此需要查阅相关文档或联系云服务提供商以获取详细信息。 2. 更新云服务器操作系统 如果云...
    99+
    2023-10-27
    不兼容 虚拟机 服务器
  • win7下xp兼容模式设置步骤解决应用程序不兼容问题
    今天为大家带来的是win7与xp兼容模式设置方法,在Windows7中,它为用户提供了一个特别的功能,那就是xp兼容模式,这是为了帮助用户们解决一些应用程序在win7不兼容而提供的,这个功能可以帮助我们解决程序在win7...
    99+
    2023-06-05
    win7 xp 兼容模式 设置 模式 步骤 兼容
  • 怎样解决IE6、IE7、IE8样式不兼容问题
    怎样解决IE6、IE7、IE8样式不兼容问题,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。这里和大家探讨一下解决IE6、IE7、IE8 DIV...
    99+
    2024-04-02
  • 云服务器装虚拟机不兼容怎么解决问题
    检查虚拟机的系统文件,确保虚拟机的系统文件与云服务器的系统文件是兼容的。 检查云服务器的系统文件中的兼容性信息,看看是否是兼容的,如果是兼容的,可以直接将虚拟机的系统文件替换到云服务器的系统文件中。 检查云服务器中的系统文件是否完整,如果...
    99+
    2023-10-26
    解决问题 不兼容 虚拟机
  • win7特别功能xp兼容模式设置方法解决程序不兼容问题
    今天为大家带来的是win7与xp兼容模式设置方法,在Windows7中,它为用户提供了一个特别的功能,那就是xp兼容模式,这是为了帮助用户们解决一些应用程序在win7不兼容而提供的,这个功能可以帮助我们解决程序在win7...
    99+
    2023-06-06
    win7 xp 兼容模式 模式 设置 兼容 方法 解决
  • IE8兼容性视图如何解决网站不兼容页面显示错乱问题
    IE8兼容性视图如何解决网站不兼容页面显示错乱问题,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。你对IE8兼容性视图解决网站不兼容页面显示错乱...
    99+
    2024-04-02
  • 如何解决win10专业版软件不兼容问题
    本篇内容介绍了“如何解决win10专业版软件不兼容问题”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!win10作为一款主流系统,在各项功能优...
    99+
    2023-06-07
  • 解决lombok父类和子类builder不兼容的问题
    目录遇到的问题排查和解决结尾遇到的问题 在写代码时,有时因为需要定义一些重复的参数,为了复用之前传参的DTO,会对原有的类进行继承,从而达到避免重复代码的效果。 但是,当父类中使用了...
    99+
    2024-04-02
  • 如何解决跨版本 PHP 函数不兼容问题?
    为了解决 php 中跨版本函数不兼容问题,可以通过使用以下策略:功能检测:检查函数是否可用,提供替代方案。polyfill:提供未实现或不完全实现函数的代码。aliasing:创建旧函数...
    99+
    2024-04-25
    php 函数兼容 mysql
  • 解决云服务器装虚拟机不兼容问题的方法
    1. 确认虚拟机和云服务器的兼容性 在解决云服务器装虚拟机不兼容问题之前,首先需要确认虚拟机和云服务器的兼容性。不同的虚拟机软件和云服务器提供商可能有不同的要求和限制。确保你选择的虚拟机软件和云服务器之间是兼容的,可以避免一些兼容性问题。...
    99+
    2023-10-27
    不兼容 虚拟机 服务器
  • 云服务器装虚拟机不兼容怎么解决问题呢
    检查虚拟机的操作系统和虚拟机的硬件是否兼容,如果不兼容,请尝试安装最新版本的操作系统以及硬件驱动程序,以保证云服务器虚拟机和虚拟机操作系统的兼容性。 检查虚拟机的操作系统的网络设置是否正确,如果网络设置不正确,可能会引起云服务器虚拟机无法...
    99+
    2023-10-27
    解决问题 不兼容 虚拟机
  • 教你解决Win8的IE10浏览器不兼容的问题
    1、如果在打开IE10游览器预览页面,当页面不兼容的时候或者网页字体拥挤。 2、可按下键盘F12调出“开发人员工具”选用IE8来游览此页面。 3、具体还是根据自己的实际情况来预览,开发人员工具...
    99+
    2023-06-03
    Win8的IE10浏览器不兼容 Win8 问题 IE10 浏览器
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作