Re: NullPointerException at listFiles
Michael B Allen <[email protected]>
| Newsgroups | gmane.network.samba.java |
|---|---|
| Message-ID | <CAGMFw4jS0CFA+7FRF6gwCZmUiM9HQFppJ1dzxz+A4SiyxZ_5YQ@mail.gmail.com> |
On Mon, Mar 5, 2012 at 4:59 PM, Gabor Herr <[email protected]> wrote: > 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) Hi Gabor, I have added this to the TODO list for further investigation. I'm not sure but I don't think setting the tconHostName in the constructor is the correct fix. In this case I think it's a good idea to minimize the number of states that the object can be in. Meaning the connection loss should reset the SmbFile back to it's pre-connection state so that there are only two states. Thanks for the test case. That will be useful. Mike > 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. > -- Michael B Allen Java Active Directory Integration http://www.ioplex.com/