大家好,我写了一个类,功能是在特定时间自动进行某些操作。但是调试的时候总出错:
Exception in thread "main" java.lang.StackOverflowError
at erip.autoreminder.<init>(autoreminder.java:19)不知道是什么意思。贴一些代码出来,大家帮看看好吗,谢谢了先!public class autoreminder 
{
    Timer timer;
    autoreminder auto = new autoreminder();
    private Connection conn = JdbcPool.getConnection();
    
    public void Reminder() 
    {
     Calendar calendar = Calendar.getInstance();
     calendar.set(Calendar.HOUR_OF_DAY, 15);
     calendar.set(Calendar.MINUTE, 30);
     calendar.set(Calendar.SECOND, 0);
     Date time = calendar.getTime();     timer = new Timer();
     timer.schedule(new RemindTask(),time); 
    }
*********************************************************
    class RemindTask extends TimerTask 
    {
      public void run()
      {
        try 
        {
          auto.Select();       
        }
        catch(Exception ef){};
        timer.cancel(); //Terminate the timer thread
        }
    }
**********************************************************
public void Select() 
{
  boolean ifsend = true; 
  try 
  {
Statement stmt = conn.createStatement();
String sqlstr="select * from sys_mentioninfo where hasmention='未提醒'";
ResultSet rs = stmt.executeQuery(sqlstr);
if(rs.next()) 
{
  rs.beforeFirst();
  while(rs.next())
  {
    ifsend = auto.timecompare(rs.getString("mentiontime").substring(0,10));
    if(ifsend)
    {
      auto.sendmessage(rs.getInt("id"),rs.getString("sdoi"),rs.getString("content"),rs.getString("serialcode"));
    }
//     else
//     {
//   rs.close();
//   stmt.close();     
//     }
  }
}
else 
{
   throw new SQLException("SQLException");
}
 } // end of try

 catch (SQLException e)
 {
e.printStackTrace();
 }
}
****************************************************************** public static void main(String[] args) 
{
  System.out.println("About to schedule task.");
  autoreminder am = new autoreminder();
  am.Reminder();
  System.out.println("Task scheduled.");
}
}

解决方案 »

  1.   

    http://hi.baidu.com/littlejava/blog/item/6261eac22cc18a190ff477b3.html
      

  2.   

    递归调用,栈溢出了~~第4行的 autoreminder auto = new autoreminder(); 可以不要,调用自己的方法就直接写方法名就可以了。class RemindTask extends TimerTask 可以改为外部类,不要使用内部类。select() 方法写得也不是很好,建议另外写一个类,把 select 写在那个类里,而且if(ifsend) 

      auto.sendmessage(...); 不要直接在数据库操作中发送,可以写个 JavaBean 使用 List 一个一个地加进去,select 返回这个 List,这样
    可以把 rs, stmt, con 都 close() 掉。在 run 方法中获得那个 List,并遍历发送就可以了。这样可以把数据库操作和Timer操作分开操作,方便维护和查错,可以去试试看。
      

  3.   

    基本的结构如下:public class autoreminder { 
        ....
        timer = new Timer(); 
        timer.schedule(new RemindTask(), time);   
    } public class RemindTask extends TimerTask {
        private void sendmessage(...) {    }    public void run() { 
            try { 
                DB db = new DB();
                List<Mentioninfo> list = db.select();
                for(int i=0, k=list.size; i<k; i++) {
                     sendmessage(list.get(i).getId(),...);
                }
            }catch(Exception ef){
                ef.printStackTrace();
            }
    } public class Mentioninfo {
        private String id;
        private String sdoi;
        private String content;
        private String serialcode;
        private String mentiontime;
        
        setter/getter
    }public class DB {    private boolean timecompare(...) {    }    public List<Mentioninfo> select() {
            List<Mentioninfo> list = new ArrayList<Mentioninfo>();
            try {
                ...各种操作
                  Mentioninfo m = new Mentioninfo();
                m.set(...);
                list.add(m);
            }catch(SQLException e) {
                e.printStackTrace();
            }finally{
                try{
                    rs.close();
                    stmt.close();
                    con.close();
                }catch(SQLException e) {
                    e.printStackTrace();
                }
            }
            return list;
        }
    }
      

  4.   

    稍稍改一下:public class autoreminder { 
        ....
        timer = new Timer(); 
        timer.schedule(new RemindTask(), time);   
    } public class RemindTask extends TimerTask {
        private void sendmessage(...) {    }    public void run() { 
            try { 
                DB db = new DB();
                List<Mentioninfo> list = db.select();
                for(int i=0, k=list.size; i<k; i++) {
                     Mentioninfo m = list.get(i);
                     sendmessage(m.getId(), ...);
                }
            }catch(Exception ef){
                ef.printStackTrace();
            }
    } public class Mentioninfo {
        private int id;
        private String sdoi;
        private String content;
        private String serialcode;
        private String mentiontime;
        
        setter/getter
    }public class DB {    private boolean timecompare(...) {    }    public List<Mentioninfo> select() {
            List<Mentioninfo> list = new ArrayList<Mentioninfo>();
            Connection con = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                boolean ifsend = true;
                con = JdbcPool.getConnection(); 
                stmt = conn.createStatement(); 
                String sqlstr= "select * from sys_mentioninfo where hasmention='未提醒'"; 
                ResultSet rs = stmt.executeQuery(sqlstr); 
                while(rs.next()) { 
                    ifsend = timecompare(rs.getString("mentiontime").substring(0,10)); 
                    if(ifsend) { 
                         Mentioninfo m = new Mentioninfo();
                         m.setId(rs.getInt("id"));
                         m.setSdoi(rs.getString("sdoi"));
                         m.setXxxx(...);
                         list.add(m);
                    }
                } 
            }catch(SQLException e) {
                e.printStackTrace();
            }finally{
                try{
                    rs.close();
                    stmt.close();
                    con.close();
                }catch(SQLException e) {
                    e.printStackTrace();
                }
            }
            return list;
        }
    }
      

  5.   

    我按照4楼的修改了代码,但是在调试的时候出错。
    为了便于调试,我加了main类作为初始调用点。代码和错误如下:
    public class Reminder 
    {
        Timer timer;
    public void start() 
    {
         Calendar calendar = Calendar.getInstance();
         timer = new Timer();
          timer.schedule(new RemindTask(),time); 
       }
    *************************************************************
    public static void main(String[] args) {
    // TODO Auto-generated method stub
         Reminder rm = new Reminder ();
         rm.start();
    }
    }
    ****************************************************************
    public class RemindTask extends TimerTask 

      private void sendmessage(int id,String sdoi,String content,String serialcode) 
      {
      }  public void run() 
      { 
        try 

      DB db = new DB();
      List<Mentioninfo> list = db.select();
      for(int i=0, k=list.size(); i<k; i++) 
      {
        Mentioninfo m = list.get(i);
        sendmessage(m.getId(),m.getSdoi(),m.getContent(),m.getSerial());
      }
         }
    catch(Exception ef)
    {
       ef.printStackTrace();
    }
      } }
    ******************************************************************
    public class DB   
    {
        private boolean timecompare(String mt)   // 该类比较当前时间与应该提醒时间的差值 
        {
        }
        
        public List<Mentioninfo> select() 
        {
            List<Mentioninfo> list = new ArrayList<Mentioninfo>();
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try 
            {
                boolean ifsend = true;
                conn = JdbcPool.getConnection();    //问题就出在这里,系统提示如下:
    *******************************************************************************
    javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    *******************************************************************************
                stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); 
                String sqlstr= "select * from sys_mentioninfo where hasmention='no'"; 
                rs = stmt.executeQuery(sqlstr); 
            }
            catch(SQLException e) 
            {
                e.printStackTrace();
            }
            finally
            {
                try
                {
                    rs.close();
                    stmt.close();
                    conn.close();
                }
                catch(SQLException e) 
                {
                    e.printStackTrace();
                }
            }
            return list;
         }
    }
    *****************************************************************
    下面是建立tomcat连接池的操作
    public static void setupDatasource() {
    try {
    Context initCtx = new InitialContext();
    ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/DBConnection");
    } catch (NamingException e) {
    e.printStackTrace();
    }
    } @SuppressWarnings("finally")
    public static Connection getConnection(){
    if(ds==null) {
    setupDatasource();
    }
    try {
    conn = ds.getConnection();
    }
    catch(SQLException e) {
    e.printStackTrace();
    }
    finally {
    return conn;
    } }************************************************************
    错误好象是连接池配置的有问题。请问和通过main调试而无法获得tomcat的配置有关系吗?
      

  6.   

    对的,main方法无法获得Tomcat JNDI连接池。