2013-07-07 32 views
0

當行clanovi =((HashMap)in.readObject())時,我得到一個EOF異常;從方法load()執行,但並非總是如此。它發生在5-6之後,有時甚至10次來自我的servlet的load方法的調用,完全是隨機的。請幫助我,我需要這個解決,明天早上項目防守:(EOFileException突然

只是說ClanPostave是序列化我嘗試添加的flush()到負載的方法,但沒有任何幫助

public class Clanovi implements Serializable { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 


HashMap<String, ClanPostave> clanovi = new HashMap<String, ClanPostave>(); 

public HashMap<String, ClanPostave> getClanovi() { 
    return clanovi; 
} 

public void setClanovi(HashMap<String, ClanPostave> clanovi) { 
    this.clanovi = clanovi; 
} 


public synchronized void save(String path){ 

    try { 

     ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path + "/clanovi.dat")); 
     out.writeObject(clanovi); 
     out.close(); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

@SuppressWarnings("unchecked") 
public synchronized void load(String path){ 

    try { 
     ObjectInputStream in = new ObjectInputStream(new FileInputStream(path + "/clanovi.dat")); 
     clanovi = ((HashMap<String,ClanPostave>) in.readObject()); 
     in.close(); 
    } catch (FileNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (ClassNotFoundException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

堆棧跟蹤。:

java.io.EOFException 
    at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) 
    at java.io.ObjectInputStream.readClassDesc(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source) 
    at java.io.ObjectInputStream.defaultReadObject(Unknown Source) 
    at java.util.Calendar.readObject(Unknown Source) 
    at sun.reflect.GeneratedMethodAccessor25.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source) 
    at java.io.ObjectInputStream.readSerialData(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source) 
    at java.io.ObjectInputStream.readSerialData(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.readObject(Unknown Source) 
    at java.util.HashMap.readObject(Unknown Source) 
    at sun.reflect.GeneratedMethodAccessor31.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source) 
    at java.io.ObjectInputStream.readSerialData(Unknown Source) 
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) 
    at java.io.ObjectInputStream.readObject0(Unknown Source) 
    at java.io.ObjectInputStream.readObject(Unknown Source) 
    at beans.Clanovi.load(Clanovi.java:52) 
    at servlets.DodajClana.doPost(DodajClana.java:51) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286) 
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845) 
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) 
    at java.lang.Thread.run(Unknown Source) 

EOFException類不見了感謝喬尼,但現在我有這個問題:

try { 
      clanovi1.dodajClana(new ClanPostave(idclana,ime,prezime,mesto,new GregorianCalendar(datumGodina, datumMesec, datumDan),biografija,uloga)); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     clanovi1.save(path); 
     clanovi1.load(path); 
     HashMap<String, ClanPostave> clanovi = clanovi1.getClanovi(); 

此代碼後HashMap爲空。在Joni提出這個改變之前,它被填充了在該try塊中添加的值。什麼可能是錯的?

這裏是整個的servlet:

package servlets; 

    import java.io.IOException; 
    import java.util.Calendar; 
    import java.util.GregorianCalendar; 
    import java.util.HashMap; 

    import javax.servlet.ServletContext; 
    import javax.servlet.ServletException; 
    import javax.servlet.http.HttpServlet; 
    import javax.servlet.http.HttpServletRequest; 
    import javax.servlet.http.HttpServletResponse; 

    import beans.ClanPostave; 
    import beans.Clanovi; 
    import beans.Korisnik; 

    /** 
    * Servlet implementation class DodajClana 
    */ 
    public class DodajClana extends HttpServlet { 
     private static final long serialVersionUID = 1L; 



     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
      request.getRequestDispatcher("index.jsp").forward(request, response); 
     } 
     /** 
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
     */ 
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
      ServletContext ctx = getServletContext(); 
      Korisnik korisnik = (Korisnik) request.getSession().getAttribute("korisnik"); 

      if(korisnik != null && korisnik.getAdmin()){ 
      String path = ctx.getRealPath(""); 
      String idclana = request.getParameter("idclana"); 
      String ime = request.getParameter("ime"); 
      String prezime = request.getParameter("prezime"); 
      String mesto = request.getParameter("mesto"); 
      int datumGodina = Integer.parseInt(request.getParameter("datumGodina")); 
      int datumMesec = Integer.parseInt(request.getParameter("datumMesec"))-1; 
      int datumDan = Integer.parseInt(request.getParameter("datumDan")); 
      String biografija = request.getParameter("biografija"); 
      String uloga = request.getParameter("uloga"); 

      System.out.println(idclana); 

      Clanovi clanovi1 = new Clanovi(); 
      clanovi1.load(path); 

      if(!isDateValid(datumGodina, datumMesec, datumDan)){ 
       System.out.println("ne valja datum"); 
       request.setAttribute("greska1", "Nevalidan datum!"); 
      } 

      if(clanovi1.getClanovi().containsKey(idclana)){ 
       System.out.println("ne valja id"); 
       request.setAttribute("greska2", "Clan sa tim ID-jem vec postoji u bazi!"); 
      } 

      if((!isDateValid(datumGodina, datumMesec, datumDan))||clanovi1.getClanovi().containsKey(idclana)){ 

       request.getRequestDispatcher("/WEB-INF/clanGreska.jsp").forward(request, response); 
      } 

      boolean test = !((!isDateValid(datumGodina, datumMesec, datumDan))||(clanovi1.getClanovi().containsKey(idclana)) || ((!isDateValid(datumGodina, datumMesec, datumDan))||clanovi1.getClanovi().containsKey(idclana))); 
      System.out.println(test); 
      if(test){ 

       try { 
        clanovi1.dodajClana(new ClanPostave(idclana,ime,prezime,mesto,new GregorianCalendar(datumGodina, datumMesec, datumDan),biografija,uloga)); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       clanovi1.save(path); 
       try { 
        System.out.println(clanovi1.getClan(idclana)); 
       } catch (Exception e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

       try { 
        System.out.println(clanovi1.getClan(idclana)); 
       } catch (Exception e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       HashMap<String, ClanPostave> clanovi = clanovi1.getClanovi(); 
       ctx.setAttribute("clanovi", clanovi);  
       request.getRequestDispatcher("index.jsp"); 
      } 

      }     

      else request.getRequestDispatcher("index.jsp").forward(request, response); 
     } 


     public synchronized boolean isDateValid(int year, int month, int day) { 
      boolean valid = true; 
      Calendar calendar = new GregorianCalendar(year, month, day); 
      if (year != calendar.get(Calendar.YEAR)) { 
       valid = false; 
      } 
      else if (month != calendar.get(Calendar.MONTH)) { 
       valid = false; 
      } 
      else if (day != calendar.get(Calendar.DAY_OF_MONTH)) { 
       valid = false; 
      } 
      return valid; 
     } 



    } 
+0

請你分享的堆棧跟蹤? – 2013-07-07 20:23:39

+0

是否有任何同步來阻止讀者閱讀不完整的文件? – Joni

+0

save()和load()有時可能被同時調用嗎? –

回答

1

的一種方式,以防止讀取不完整的文件被寫入到一個臨時文件,然後重命名它:

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(path + "/clanovi.tmp")); 
    out.writeObject(clanovi); 
    out.close(); 
    new File(path + "/clanovi.tmp").renameTo(new File(path + "/clanovi.ovi")); 

這意味着load過程現在可以在第一次運行時沒有找到該文件,或者可能會讀取舊數據。

+0

感謝隊友,這解決了EOFException問題,但如果可以的話,請看我最後編輯的第一篇文章。 – kecman

-1

也許你可以使用同步塊/函數加載並保存到序列化文件。

喜歡的東西 -

public enum Operation { 
      LOAD, 
      SAVE;  
} 

synchronized void loadOrSave(String path, Operation operation) { 
    if (operation == Operation.LOAD) { 
     //do load here 
    } else { 
     //do save here 
    } 

} 
+0

文件鎖只能在進程之間使用。這一切都發生在同一個過程中。 – EJP

+0

EJP - 你能解釋一下嗎,可能有些鏈接可以證明你的觀點? –

+0

沒關係,我明白了。謝謝。 –