动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.JAVA对JPEG图片进行处理.
.J2SE中的序列化详解(一).
.CGLib实现变化字段探测的供能.
.使用JSR-184里的Sprite3D对象.
.Java基础知识 Java Web三层架构的.
.用Java将文件名从中文转为拼音.
.在Wicket里面使用一个自己WebSes.
.面向对象编程之:Java collectio.
.Cell插件在J2EE系统中的应用.
.高级应用 java多线程设计模式详解.
.java日记(3) 类的初始化问题(CS.
.Exo rc-ow版本正式发布.
.EJB 自管理的事务.
.调整 Java I/O 性能.
.为何要使用 UML?.
.随机数 获取背景音乐.
.JDK Observer设计模式之研究.
.Java中的Sizeof(二).
.深入讨论JSF中Tree2组件使用方法.
.Javascript 中 浅拷贝与深拷贝的.

克服J2SE 1.3 ~ 1.4不兼容问题 HK2000c

发表日期:2008-1-5 |



  概要
  假如你要实现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 语句就可以了:
  <replace>
  <replacetoken>Comment_next_line_for_Java_1.3
  </replacetoken>
  <replacevalue>Comment_next_line_for_Java_1.3
  //</replacevalue>
  </replace>
  
  这个Ant 的 replace 标签 有好几个标签选项,在以后我给出的全部例子里有很多。在这里面最重要的是使用<replacevalue>来替换<replacetoken> 。
  在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;
  
  /** Dummy class to allow ConnectionWrapper to implement java.sql.Connection
  * and still compile under J2SE 1.3 and J2SE 1.4. When compiled
  * under J2SE 1.3, this class compiles as a placeholder instead of the
  * missing java.sql.Savepoint (not in J2SE 1.3). When compiled
  * under J2SE 1.4, this class is ignored and ConnectionWrapper uses the
  * java.sql.Savepoint that is new in J2SE 1.4.
  */
  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];<
上一篇:软件过程的发展的思考 人气:349
下一篇:Java 应用程序中的按值传递语义以及相关评论 人气:386
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-29 oblog v4.6 build 20080827
2008-8-29 ASBLOG v2.5 bulid 080828
2008-8-29 时尚DJ舞曲小偷 v3.1
2008-8-29 仿代码信息分类系统 v1.0 Beta3
2008-8-29 浮梦呓语-个人网站 完整版
2008-8-29 多用户QQ空间Flash播放器
2008-8-29 美思卡企业网站管理系统高级版
2008-8-28 LDV个人相册系统 v1.6.1
2008-8-28 讯时网站管理系统CMS v3.5
2008-8-23 Mini WinMount V0.4
2008-8-23 Vista优化大师3.11正式版
2008-8-23 Wine 1.13
2008-8-23 KlipFolio 5.0 Build 5899-80
2008-8-23 Windows Sysinternals Desktops
2008-8-23 OneTap Movies1.2破解版
2008-8-23 AnnotaterPDF阅读1.1.503 破解版
2008-8-23 SoundMeter分贝测量仪 v1.0汉化破
2008-8-23 iDrum音乐节拍1.0破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | Html转换js | js/vbs加密 | md5加密 | 进制转换
实用工具:汉字翻译拼音 | 符号对照表 | 个税计算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号