2006年05月25日

        为了配置struts的数据源,搞了两天,都快疯了。查了n多的资料,试验了无数次,终于搞成了,最终的配置如下:
  <data-sources>
     <data-source key="mysql datasource" type="org.apache.commons.dbcp.BasicDataSource">
         <set-property property="driverClassName" value="org.gjt.mm.mysql.Driver" />
         <set-property property="url" value="jdbc:mysql://localhost/stocks" />
         <set-property property="username" value="root" />
         <set-property property="password" value="2131018" />
         <set-property property="minCount" value="2" />
         <set-property property="maxCount" value="10" />
      </data-source>
 </data-sources>
       不过成功是成功了,还是有些问题没搞清楚。主要是属性名称方面。很多资料里面JDBC驱动的属性名为driverClass,设置用户的属性名为user。不知道具体如何,还是这两种都可以呢?

    

struts-config.xml中的元素有严格的顺序,如果元素的顺序出错,系统会抛出一个错误,描述如下:
The content of element type "struts-config" must match "(display-name?,description?,data-sources?,form-beans?,global-exceptions?,global-forwards?,
action-mappings?,controller?,message-resources*,plug-in*)". [109]
刚看到这个错误,我总以为是某个元素的拼写出了错误,把整个文件仔细检查了一遍,没有发现任何拼写作错误。查了资料才知道,struts-config.xml中的元素有严格的顺序,他们的顺序应该是象下面这个样子:

<struts−config>
<data−sources>
<data−source>
</data−source>

</data−sources>
<form−beans>

<form−bean />

</form−beans>
<global−forwards>

<forward />

</global−forwards>
<action−mappings>

<action/>

</action−mappings>
<controller />
<message−resource />
<plug−in />

</struts−config>
上面的错误提示不是说元素有拼写错误,而是说struts-config.xml必须按照display-name–>description–>datasources–>form-beans–>global-forwards–>action-mappings–>controller–>message_resources–>plug-in的顺序书写。


2004年11月29日

        一直以来都想在自己的代码中实现编译和运行,主要是基于这样的想法,假如用户能够根据自己的要求编写一些脚本,这样,很多维护工作就可以由具有相当经验的用户自己完成,避免因为需求一点点变动就修改源代码。前一阵子,我根据自己的理解编写了一下代码:
  public void compileAFile()
 {
  StringBuffer sb=new StringBuffer();
  sb.append("javac ");
  sb.append(this.srcFileName);
  if(this.destFileName!=null && this.destFileName!="")
  {
   sb.append(" -d ");
   sb.append(System.getProperty("java.class.path"));
  }
  Runtime rt=Runtime.getRuntime();
  try{
  System.out.println(sb.toString());
  Process p=rt.exec(sb.toString());
  p.waitFor();
  InputStream error=p.getErrorStream();
  byte[] buf=new byte[1024];
  while(error.available()!=0){
   int num=error.read(buf);
   String outStr=new String(buf,0,num,"utf-8");
   System.out.println(outStr);
  }
  }catch(Exception e){
   e.printStackTrace();
  }
 }
public void runAFile()
 {
  try{
  //String classpath=System.getProperty("java.class.path");
  //System.out.println(classpath);
  System.out.println(this.destFileName);
  Class cl=this.getClass().getClassLoader().loadClass(this.destFileName);
  Object ob=cl.newInstance();
  Method md=cl.getMethod("execute",null);
  md.invoke(ob,null);
  }catch(Exception e){
   e.printStackTrace();
  }
 }
compileAFile用来编译一个类,runAFile用来运行一个类中的已知的方法.  这样的确能够编译和运行一个类,但总觉得不好,主要是调用系统中的一个可运行程序,结果不好控制,后来看到jasperreport,这是其中的一段代码:
public String compileClass(File sourceFile, String classpath) throws JRException
 {
  String[] source = new String[3];
  source[0] = sourceFile.getPath();
  source[1] = "-classpath";
  source[2] = classpath;
  
  //ByteArrayOutputStream baos = new ByteArrayOutputStream();
  String errors = null;

  try
  {
   Class clazz = JRClassLoader.loadClassForName("com.sun.tools.javac.Main");
   Object compiler = clazz.newInstance();
   //Method compileMethod = clazz.getMethod("compile", new Class[] {String[].class, PrintWriter.class});
   Method compileMethod = clazz.getMethod("compile", new Class[] {String[].class});

   int result = ((Integer)compileMethod.invoke(compiler, new Object[] {source})).intValue();
   if(result != MODERN_COMPILER_SUCCESS)
   {
    errors = "See error messages above.";
   }
  }
  catch (Exception e)
  {
   throw new JRException("Error compiling report java source file : " + sourceFile, e);
  }

  /*
  if( baos.toString().indexOf("error") != -1 )
  {
   return baos.toString();
  }
  */
  
  return errors;
 }
当然,这是对jdk1.3的