[jcifs] NullPointerException at listFiles

Michael B Allen ioplex at gmail.com
Mon Mar 5 23:22:59 MST 2012


On Mon, Mar 5, 2012 at 4:59 PM, Gabor Herr <gabor.e.herr at googlemail.com> wrote:
> 2012/3/5 Michael B Allen <ioplex at gmail.com>
>>
>>
>> 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/


More information about the jCIFS mailing list