UNIX平台的Domino程序查询sql server数据库数据 - IBM Lotus Notes 的一个产品缺陷

事件背景

 

         原来的Domino系统安装在windows 2003服务器上。

         两年前,根据领导的需求,写了一个调用人力资源系统数据库的 Domino代理程序。 这个代理每2个小时自动

运行一次,通过OLE DB取到人力资源数据库的数据,加工后,保存到一个domino数据库的文档里。

 

          这个代理使用Lotus Script开发, 人力资源数据库是MS SQL SERVER 2000。 代码与VB非常相近,

例如:   Set Conn = CreateObject("ADODB.Connection")
            Conn.Open DBConStr

 

            Set RS=CreateObject("ADODB.Recordset")

            RS.Open SQLCmd,Conn,adOpenStatic,adLockOptimistic,adCmdText

 

         因为服务器的操作系统是windows 2003,调用ADODB没有任何问题,非常方便快捷。

 

 

平台变动

            最近,windows2003服务器退役了。 Domino系统移植到 IBM AIX服务器。 邮箱等办公应用

   没有问题。  但是上面的代理程序根本无法运行。

 

故障现象

            这个代理程序运行了2年,没有问题,为什么突然不行了。 我打开Domino Designer, 重新编译,

完全正确。 点击“运行”菜单, 结果完全正常, 文档中保存了 人力资源系统的正确数据。

 

           2个小时后,当代理自动运行了一次,domino文档中的数据全部丢失了。

           怎么回事?  在本人电脑安装的开发环境下,完全正常。 

           打开服务器的监控台,查看该代理后续的运行记录, 提示的出错信息,大意是“系统不支持createobject语句”。

 

           终于反应过来, windows 2003支持ole db和adodb, 我的客户端win xp 也支持ole db和 adodb, 所以

  原先运行该代理程序完全正常。  而代理在服务器上定时运行时, UNIX操作系统根本不支持OLE DB(底层没有这个组件),

  所以代理无法运行。

 

 

解决方案

一、测试AIX 服务器的java 环境

    在服务器上运行 java -version

    确认 java版本是 1.5.0, IBM j9 VM

 

    编辑/etc/environment文件,在系统参数配置path中加入 /usr/java5/bin:/usr/java5/jre/bin

二、配置连接SQL SERVER数据库的jdbc程序

         在微软网站 http://www.microsoft.com/downloads/en/default.aspx,搜索jdbc,

    下载  sqljdbc_3.0.1301.101_enu.tar.gz 。

    将文件上传到服务器,运行以下命令解压。

     gzip -d  sqljdbc_3.0.1301.101_enu.tar.gz , 解压ZIP文件 为一个tar文件。

     tar –xf   sqljdbc_3.0.1301.101_enu.tar ,解压 tar文件 为一个文件夹。

 

     解压后,在sqljdbc_3.0目录下,发现有sqljdbc.jar 和 sqljdbc4.jar两个文件。

 

 

     sqljdbc.jar 类库提供对 JDBC 3.0 的支持。

     sqljdbc.jar 类库要求使用 5.0 版的 Java 运行时环境 (JRE)。连接到数据库时,在 JRE 6.0 上

使用 sqljdbc.jar 会引发异常。

 

 

     sqljdbc4.jar 类库提供对 JDBC 4.0 的支持。它不仅包括 sqljdbc.jar 的所有功能,还包括新增的 JDBC 4.0 方法。

     sqljdbc4.jar 类库要求使用 6.0 或更高版本的 Java 运行时环境 (JRE)。在 JRE 1.4 或 5.0 上使用 sqljdbc4.jar 会引发异常。

     注意: 如果应用程序必须在 JRE 6.0 上运行,即使该应用程序不使用 JDBC 4.0 功能,也应使用 sqljdbc4.jar。
     综上所述,我选用sqljdbc.jar, 将其复制到/usr/java5/bin。
     同时, 编辑/etc/environment文件,加入 classpath = /usr/java5/bin/sqljdbc.jar
 
     最后, 使用 ls -l 命令,你就会发现 sqljdbc.jar 仅有读写权限 (-rw-r--r--), 需要增加执行(e xecute)权限。
     运行 chmod  755  sqljdbc.jar 即可。
     编写了一个java程序,使用jdbc调用SQL SERVER 数据库数据,编译运行完全正常。
     但是,我发现在notes中同样的程序根本无法运行起来。
 
三、代码

 

   以前的 OLE DB  ADO 代码很简单。(LotusScript )

   Dim Conn As Variant
   Dim RS As Variant
   Dim DBConStr As String
   Dim SQLCmd As String


   1、连接字符串
       DBConStr = "Provider=SQLOLEDB.1;Persist Security Info=True" & _
       ";Data Source=xxx.xxx.xx.xxx;User Id=uu;Password=pp;Connect Timeout = 100;" & _
       "Initial Catalog=hrweb;"
 

    2、创建连接对象、记录集对象


     'Create and Open Connection Object
     Set Conn = CreateObject("ADODB.Connection")
     Conn.Open DBConStr
 
      'Sql Command
 
      SQLCmd = "select *  FROM A01  a,K20 b,NA01 c " & _
                       " WHERE a.A0188=b.A0188  And a.a0188=c.a0188  order by K2007 DESC"
 
      'Create and Open Employee Recordset Object
      Set RS=CreateObject("ADODB.Recordset")

 

 

     3、打开记录集,循环提取数据
      RS.Open SQLCmd,Conn,adOpenStatic,adLockOptimistic,adCmdText
 
      RS.MoveFirst
      While Not RS.EOF
                Set uidoc = New NotesDocument(db)
                '新建文档
                uidoc.form = "ManagerVacationRecord" 
  
                Call uidoc.ReplaceItemValue("fldName",Cstr( RS("mName").Value ) )
                Call uidoc.save(True,True) 
  
                RS.MoveNext
       Wend
 

   4、关闭连接
   Conn.Close

 

 

   JDBC代码,其中释放对象内存的代码为后来增加  (Java )

   Document doc = null;
   Session session = null;
   Database db = null;
   AgentContext agentContext = null; 
           
   try {
         session = getSession();
         agentContext = session.getAgentContext();

          db = agentContext.getCurrentDatabase();
   
          System.out.println("删除历史数据开始");
       
          DocumentCollection dc = db.getAllDocuments();
          dc.removeAll(true);
          System.out.println("删除历史数据结束");
          

          String connectionUrl = "jdbc:sqlserver://xxx.xxx.xx.xxx:1433;databaseName=hrweb;user=uu;password=pp";

      

          // Declare the JDBC objects.
          Connection con = null;
          Statement stmt = null;
          ResultSet rs = null;

  
          try {
             System.out.println("start");         //供调试使用
              
             Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
             con = DriverManager.getConnection(connectionUrl);
             String SQL = "select *  FROM A01  a,K20 b,NA01 c " & _
                       " WHERE a.A0188=b.A0188  And a.a0188=c.a0188  order by K2007 DESC"
 
             stmt = con.createStatement();
             rs = stmt.executeQuery(SQL);
                     
             while (rs.next()) {
               doc = db.createDocument();
               doc.appendItemValue("form","ManagerVacationRecord");
               doc.appendItemValue("fldName",rs.getString("mName"));
               doc.appendItemValue("fldStartDate",rs.getString("mStart"));
               doc.appendItemValue("fldEndDate",rs.getString("mEnd"));
               doc.appendItemValue("fldDays",rs.getString("mDays"));

               

               SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd"); 
               Date date= myFormatter.parse(rs.getString("mStart")); 
               Date NowDate=new Date();
                     
               if(date.getTime()-NowDate.getTime()>0)
                   doc.appendItemValue("fldVacationType",rs.getString("mType")+"(未休)");
               else   
                    doc.appendItemValue("fldVacationType",rs.getString("mType")+"(在休)");
                       
                if (doc.save())
                     System.out.println("Document has been saved");
                else
                     System.out.println("Unable to save document");

                doc.recycle();
                doc = null;
                                          
              } 
                 System.out.println("end");
            }
       
            // Handle any errors that may have occurred.
            catch (Exception e) {
                     e.printStackTrace();
                }

            finally {
                           if (rs != null) try { rs.close(); rs=null; } catch(Exception e) {}
                           if (stmt != null) try { stmt.close(); stmt=null; } catch(Exception e) {}
                           if (con != null) try { con.close(); con=null; } catch(Exception e) {}
             }

           }        catch(Exception e) {   e.printStackTrace();     }
           finally{
           

              try{
                   if (doc != null) {  doc.recycle(); doc=null; }
                   if (db !=null ) {  db.recycle(); db=null; }
                   if (agentContext != null) {  agentContext.recycle();  agentContext=null; }
                   if (session != null) {session.recycle(); session=null; }
              }
                 catch(Exception e){   e.printStackTrace();     }
          }
        }
       

 

 

四、lotus notes  修改配置,使用JDBC

 

        前面提到了从微软网站下载 JDBC Driver,  Louts Notes中的 Java代码,

   但是,将二者结合起来,需要在lotus notes 中修改配置。

 

        在网上找到一个传统的Notes Java 开发说明。 在Lotus Designer 编写java程序的窗口中,

   找到“编辑项目”按钮,点击后进入 “组织Java代理文件”对话框中,将JDBC Driver文件sqljdbc.jar

   加载进来,采用相对文件路径。

        我在客户端的相对路径下也放了一个sqljdbc.jar文件,代码在客户端测试能够正常运行。

        但是,我做的是一个定时自动运行的代理程序,完全在服务器运行,原以为“代理”程序加载了

   sqljdbc.jar后, lotus notes 会自动在服务器Java路径下找到此驱动并运行,结果令人失望。

   在AIX服务器的相对路径下,我又放了一份sqljdbc.jar文件, 仍旧跑不起来。

 

   最后,通过在Domino 服务器配置设置中,在 Notes.ini设置中加上

 

                 JavaUserClassesExt = ST00

                 ST00=/mail/notesdata/domino/java/sqljdbc.jar

 

         才最终解决此一问题。  注意, notes不使用服务器java环境下的程序,它仅调用/domino/java

         目录下的驱动程序。

 

五、总结

       

            这个程序原先使用OLE DB ADO开始时,只用了一个工作日就完成了。 但是,迁移此程序却用了一周时间。

 

           迁移过程的关键点在于:

            1、java 程序中必须在对象使用完毕后,立刻清除对象;   这是一个很奇怪的事情,java标准中,内存

      回收是垃圾收集器的事情,在Notes中不及时清除对象并回收内存,会立刻造成系统宕机的恐怖后果。

               我以为这是IBM notes产品的一个重大缺陷;

 

            2、sqljdbc.jar的配置问题。为什么使用 Designer这样的开发工具配置后,仍然不能使程序正常运行?

      这样的开发环境有何用处。 微软开发工具的易用性众所周知,对比下来IBM 的产品在这方面远远落后,帮助文件

      写的不全面,开发资料也相当少。 运行一个java 程序,要求程序员去干系统管理员做的事,太夸张了。

 

             总之,IBM notes开发相对使用其他开发工具来说,的确是件痛苦的事情。IBM在我心目中的地位大打折扣。

 

             以上还有若干细节描述得不够清楚,以后再逐步补充。

 

 

 

       

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值