[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