Re: NullPointerException at listFiles
Gabor Herr <[email protected]>
| Newsgroups | gmane.network.samba.java |
|---|---|
| Message-ID | <CACH_Ci8gbcjUGvOD6vq5TveYUGBx4o30ZWedv2UjVQtu61i78A@mail.gmail.com> |
2012/3/5 Michael B Allen <[email protected]> > > Hi Gabor, > > I don't think it's a good idea to set the tconHostName in the constructor. > > Please post the full NPE stack trace. > > Mike > > Hi Mike, the stack trace is exactly the same as reported by Dora: *java.lang.NullPointerException* at jcifs.smb.Dfs.resolve(*Dfs.java:169*) at jcifs.smb.SmbFile.resolveDfs(*SmbFile.java:671*) at jcifs.smb.SmbFile.send(*SmbFile.java:773*) at jcifs.smb.SmbFile.doFindFirstNext(*SmbFile.java:1986*) at jcifs.smb.SmbFile.doEnum(*SmbFile.java:1738*) at jcifs.smb.SmbFile.listFiles(*SmbFile.java:1715*) at jcifs.smb.SmbFile.listFiles(*SmbFile.java:1648*) at Test$Browser.run(*Test.java:25*) at java.lang.Thread.run(*Thread.java:662*) At first we only changed the finally block, but that did not fix the problem. Only after setting tconHostName in the constructor jcifs was able to recover from a temporary connection loss. We use the following test code to reproduce the problem: Test.java: --------------------------------------------------------------------------------------------------------------------------------------------------------------- import jcifs.smb.NtlmPasswordAuthentication; import jcifs.smb.SmbFile; public class Test { public class Browser implements Runnable { private int id; public Browser(int n) { id = n; } @Override public void run() { for (int n = 0; n < 1000; n++) { NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("domain", "user", "passwd"); try { System.out.println("Thread " + id + " browsing folder."); SmbFile file = new SmbFile("smb://server/dir/", auth); file.listFiles(); } catch (Exception e) { e.printStackTrace(); } } } } public static void main(String[] args) { new Test().run(); } public void run() { try { jcifs.Config.setProperty( "jcifs.netbios.wins", "XX.XX.XX.XX" ); for (int n = 0; n < 50; n++) { new Thread(new Browser(n)).start(); Thread.sleep(200); } } catch (Exception e) { e.printStackTrace(); } } } ------------------------------------------------------------------------------------------------------------------------------------------------------------- The multiple theads are needed to create a significant load. While the test case is running, we simulate a network error by simply pulling the network cable and reconnect it again. Without the changes I've posted jcifs cannot recover and persistently throws NPEs at Dfs.resolve, because tconHostName is null. With both changes applied, the connection is recovered and no exception is thrown, no matter how often we interrupt the connection. Setting tconHostName in the constructor ensures, that it is matching the IP address, which is also stored there. In a reconnect attempt the host name is not passed in, that's why the error occurs.