Re: NullPointerException in Dfs.resolve

"Vella, Shon" <[email protected]> Mon, 15 Jun 2015 08:46:51 -0600
Newsgroups gmane.network.samba.java
Message-ID <CAND51tQSUJEvhXkX8ZEY88FiGgEXPvndasAx1YGwRGzRODDV5A@mail.gmail.com>
--20cf3079b68832a19e05188f8705
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

One of the patches from google submitted to the list last year:

http://article.gmane.org/gmane.network.samba.java/9410

has an attempted fix of this.

https://code.google.com/p/google-enterprise-connector-file-system/source/de=
tail?r=3D563

It seems to work for me - in any case it shouldn't ever throw that NPE out
of resolveDfs.


*Shon Vella*
*Identity Automation*
Product Engineer
281-220-0021 x2030 office
281-817-5579 fax
www.identityautomation.com

On Mon, Jun 15, 2015 at 5:45 AM, Martin Kutter <[email protected]>
wrote:

> Thanks for your reply.
> I've tested 1.3.18b - it does not fix this specific error.
>
> Regarding the fix suggested by Conrad: In the meantime, I've also
> implemented a fix for the issue - I changed SmbFile.resolveDfs()
> (lines 671 and following) to
>
> DfsReferral dr =3D null;
> // disconnect is synchronized to transport, too.
> // make sure our transport doesn't get disconnected while
> // we're inside the synchronized block
> synchronized (tree.session.transport) {
>     if (tree.session.transport.tconHostName =3D=3D null) {
>         // disconnect properly if connection is lost
>         tree.treeDisconnect(false);
>     }
>     tree.session.transport.connect();
>     dr =3D dfs.resolve(tree.session.transport.tconHostName,
>         tree.share,
>         unc,
>         auth);
> }
> if (dr !=3D null) {
>
>
> As my knowledge of CIFS is quite limited, I have no idea whether this
> is right (or has bad side effects).
>
> The idea behind is similar (but not equal) to Conrad's fix: In case the
> transport has disconnected, disconnect properly and reconnect.
>
> Best regards,
>
> Martin
>
> On Sun, 14 Jun 2015 11:37:48 -0400, Michael B Allen <[email protected]>
> wrote:
> > I have added this post to the list of people who have reported it to
> > the TODO list so that it can be considered when I get around to
> > looking at this.
> >
> > Note that the 1.3.18b mentioned in the link cited is here:
> >
> >    http://jcifs.samba.org/old/jcifs-1.3.18b.jar
> >
> > Although I cannot recall what it actually does anymore it might be
> > worth a try. We never received feedback about it.
> >
> > Mike
> >
> > On Sun, Jun 14, 2015 at 5:00 AM, Conrad Herrmann <[email protected]>
> > wrote:
> >> Martin,
> >>
> >>
> >>
> >> I have recently run into the same problem.
> >>
> >>
> >>
> >> I think the problem is that SmbFile.resolveDfs() uses the currently
> >> connected transport as the DFS resolver/domain server
> >> (tree.session.transport.tconHostName), but it is very possible that
> >> there is
> >> no currently connected transport.  In your case, that happens when the
> >> file
> >> server forces the TCP connection to close, and the transport tears
> itself
> >> down.
> >>
> >>
> >>
> >> And, although the resolveDfs() method calls connect0(), in fact this
> does
> >> nothing because doConnect() doesn't force creation of a new connection
> >> if we
> >> are talking about a DFS resolved path.
> >>
> >>
> >>
> >> It seems to me that in that case, we have to start over again at the
> top
> >> of
> >> the referral tree, with the Domain.
> >>
> >>
> >>
> >> So my solution has this:  change the code for SmbFile.resolveDfs()
> lines
> >> 671
> >> (or so) so that it says:
> >>
> >>
> >>
> >>         connect0();
> >>
> >>
> >>
> >>>        String hostName =3D tree.session.transport.tconHostName;
> >>
> >>>        String domainDfsServerName =3D getServerWithDfs();
> >>
> >>>        if (hostName =3D=3D null)
> >>
> >>>            hostName =3D domainDfsServerName;
> >>
> >>
> >>
> >>         DfsReferral dr =3D dfs.resolve(
> >>
> >>>                    hostName,
> >>
> >>                     tree.share,
> >>
> >>                     unc,
> >>
> >>                     auth);
> >>
> >>
> >>
> >> The code comes from the other use of tconHostName, in
> >> SmbFile.doConnect():
> >>
> >>         String hostName =3D getServerWithDfs();
> >>
> >>         tree.inDomainDfs =3D dfs.resolve(hostName, tree.share, null,
> auth)
> >>         !=3D
> >> null;
> >>
> >> In this code, we are getting the DFS resolver (which might be the
> domain
> >> server) as the hostName, and asking it to resolve our share.
> >>
> >>
> >>
> >> Basically what this new code is saying is that:
> >>
> >> - in the case where the transport has closed (ie, because of a timeout
> or
> >> TCP close on the DFS server side) reconnect to the DFS domain server i=
n
> >> order to resolve a share's DFS server.
> >>
> >>
> >>
> >> I can imagine a case where this doesn't work--if we have multiple
> levels
> >> of
> >> DFS redirection, where the domain server cannot redirect the client to
> a
> >> deep subdirectory.  But, I don't even know if this is possible in DFS.
> >> If
> >> it is, then at least this solution removes the top level case and
> >> identifies
> >> the problem, which would require walking down the DFS resolution path
> to
> >> resolve the actual file server.
> >>
> >>
> >>
> >> Conrad Herrmann
> >>
> >> Primdaesk, Inc.
> >>
> >>
> >>
> >>> Hi,
> >>
> >>>
> >>
> >>> I encountered a NullpointerException similar to
> >>
> >>> https://lists.samba.org/archive/jcifs/2012-January/009856.html - at
> >>
> >>> least the stack traces are similar.
> >>
> >>>
> >>
> >>> My Environment (Client side):
> >>
> >>> - jcifs 1.3.18
> >>
> >>> - IBM JDK 7
> >>
> >>> - AIX 7.1
> >>
> >>>
> >>
> >>> The NPE occured in a (in-house) plugin for the Jenkins build server.
> In
> >>
> >>> this system, JCIFs is used to recursively copy files from a Windows
> >>
> >>> share to an AIX machine.
> >>
> >>>
> >>
> >>> Re-running a build shortly after it finished triggered the NPE.
> >>
> >>>
> >>
> >>> After some debugging, it seems to me like the SmbFile=E2=80=99s under=
lying
> >>
> >>> transport is closed (by timeout), and when SmbFile.resolveDfs is
> called,
> >>
> >>> the transport is not reconnected (unlike, for example, later in
> >>
> >>> SmbFile.resolve, or in SmbSession.getChallenge).
> >>
> >>>
> >>
> >>> I was able to reproduce the NPE during debugging using the following
> >>
> >>> steps:
> >>
> >>> - Trigger a build (recursively copying from a CIFS DFS tree)
> >>
> >>> - Wait until the transport objects disconnect by timeout (tracked by
> >>
> >>> breakpoint)
> >>
> >>> - Retrigger the build (recursively copying the same directory
> structure)
> >>
> >>>
> >>
> >>> The Jenkins plugin usually runs the second JCIFS copy operation in th=
e
> >>
> >>> same thread than the first (though that's not guaranteed).
> >>
> >>> Each run uses a new SmbFile object.
> >>
> >>>
> >>
> >>> Am I missing something (like some close operation on SmbFile)?
> >>
> >>> Is this a known error?
> >>
> >>> Can I do something to fix it?
> >>
> >>>
> >>
> >>> Best regards,
> >>
> >>>
> >>
> >>> Martin
> >>
> >>>
>

--20cf3079b68832a19e05188f8705
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">One of the patches from google submitted to the list last =
year:<div><br></div><div><a href=3D"http://article.gmane.org/gmane.network.=
samba.java/9410">http://article.gmane.org/gmane.network.samba.java/9410</a>=
<br></div><div><br></div><div>has an attempted fix of this.</div><div><br><=
/div><div><a href=3D"https://code.google.com/p/google-enterprise-connector-=
file-system/source/detail?r=3D563">https://code.google.com/p/google-enterpr=
ise-connector-file-system/source/detail?r=3D563</a><br></div><div><br></div=
><div>It seems to work for me - in any case it shouldn&#39;t ever throw tha=
t NPE out of resolveDfs.</div><div><br></div></div><div class=3D"gmail_extr=
a"><br clear=3D"all"><div><div class=3D"gmail_signature"><div dir=3D"ltr"><=
div style=3D"font-size:15px;padding-left:5px"><strong><font color=3D"#00000=
0">Shon Vella</font></strong><br></div><div style=3D"font-size:15px;color:r=
gb(229,37,38);padding-left:5px"><b>Identity Automation</b></div><div style=
=3D"font-size:15px;padding-left:5px"><font color=3D"#000000">Product Engine=
er</font></div><div style=3D"font-size:15px;padding-left:5px">281-220-0021 =
x2030=C2=A0<span style=3D"color:rgb(229,37,38)">office</span></div><div sty=
le=3D"font-size:15px;padding-left:5px"><a href=3D"tel:281-817-5579" value=
=3D"+12818175579" style=3D"color:rgb(17,85,204)" target=3D"_blank">281-817-=
5579</a>=C2=A0<span style=3D"color:rgb(229,37,38)">fax</span></div><div sty=
le=3D"font-size:15px;padding-left:5px"><a href=3D"http://www.identityautoma=
tion.com/" style=3D"color:rgb(17,85,204)" target=3D"_blank">www.identityaut=
omation.com</a></div></div></div></div>
<br><div class=3D"gmail_quote">On Mon, Jun 15, 2015 at 5:45 AM, Martin Kutt=
er <span dir=3D"ltr">&lt;<a href=3D"mailto:[email protected]" target=
=3D"_blank">[email protected]</a>&gt;</span> wrote:<br><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex">Thanks for your reply.<br>
I&#39;ve tested 1.3.18b - it does not fix this specific error.<br>
<br>
Regarding the fix suggested by Conrad: In the meantime, I&#39;ve also<br>
implemented a fix for the issue - I changed SmbFile.resolveDfs()<br>
(lines 671 and following) to<br>
<br>
DfsReferral dr =3D null;<br>
// disconnect is synchronized to transport, too.<br>
// make sure our transport doesn&#39;t get disconnected while<br>
// we&#39;re inside the synchronized block<br>
synchronized (tree.session.transport) {<br>
=C2=A0 =C2=A0 if (tree.session.transport.tconHostName =3D=3D null) {<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 // disconnect properly if connection is lost<br=
>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 tree.treeDisconnect(false);<br>
=C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 tree.session.transport.connect();<br>
=C2=A0 =C2=A0 dr =3D dfs.resolve(tree.session.transport.tconHostName,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 tree.share,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 unc,<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 auth);<br>
}<br>
if (dr !=3D null) {<br>
<br>
<br>
As my knowledge of CIFS is quite limited, I have no idea whether this<br>
is right (or has bad side effects).<br>
<br>
The idea behind is similar (but not equal) to Conrad&#39;s fix: In case the=
<br>
transport has disconnected, disconnect properly and reconnect.<br>
<br>
Best regards,<br>
<br>
Martin<br>
<br>
On Sun, 14 Jun 2015 11:37:48 -0400, Michael B Allen &lt;<a href=3D"mailto:i=
[email protected]">[email protected]</a>&gt;<br>
wrote:<br>
<div class=3D"HOEnZb"><div class=3D"h5">&gt; I have added this post to the =
list of people who have reported it to<br>
&gt; the TODO list so that it can be considered when I get around to<br>
&gt; looking at this.<br>
&gt;<br>
&gt; Note that the 1.3.18b mentioned in the link cited is here:<br>
&gt;<br>
&gt;=C2=A0 =C2=A0 <a href=3D"http://jcifs.samba.org/old/jcifs-1.3.18b.jar" =
rel=3D"noreferrer" target=3D"_blank">http://jcifs.samba.org/old/jcifs-1.3.1=
8b.jar</a><br>
&gt;<br>
&gt; Although I cannot recall what it actually does anymore it might be<br>
&gt; worth a try. We never received feedback about it.<br>
&gt;<br>
&gt; Mike<br>
&gt;<br>
&gt; On Sun, Jun 14, 2015 at 5:00 AM, Conrad Herrmann &lt;<a href=3D"mailto=
:[email protected]">[email protected]</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt; Martin,<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; I have recently run into the same problem.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; I think the problem is that SmbFile.resolveDfs() uses the currentl=
y<br>
&gt;&gt; connected transport as the DFS resolver/domain server<br>
&gt;&gt; (tree.session.transport.tconHostName), but it is very possible tha=
t<br>
&gt;&gt; there is<br>
&gt;&gt; no currently connected transport.=C2=A0 In your case, that happens=
 when the<br>
&gt;&gt; file<br>
&gt;&gt; server forces the TCP connection to close, and the transport tears=
<br>
itself<br>
&gt;&gt; down.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; And, although the resolveDfs() method calls connect0(), in fact th=
is<br>
does<br>
&gt;&gt; nothing because doConnect() doesn&#39;t force creation of a new co=
nnection<br>
&gt;&gt; if we<br>
&gt;&gt; are talking about a DFS resolved path.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; It seems to me that in that case, we have to start over again at t=
he<br>
top<br>
&gt;&gt; of<br>
&gt;&gt; the referral tree, with the Domain.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; So my solution has this:=C2=A0 change the code for SmbFile.resolve=
Dfs()<br>
lines<br>
&gt;&gt; 671<br>
&gt;&gt; (or so) so that it says:<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0connect0();<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 String hostName =3D tree.session.tr=
ansport.tconHostName;<br>
&gt;&gt;<br>
&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 String domainDfsServerName =3D getS=
erverWithDfs();<br>
&gt;&gt;<br>
&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (hostName =3D=3D null)<br>
&gt;&gt;<br>
&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hostName =3D domainDf=
sServerName;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0DfsReferral dr =3D dfs.resolve(<b=
r>
&gt;&gt;<br>
&gt;&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 hostName,<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0tree.share,<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0unc,<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0auth);<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; The code comes from the other use of tconHostName, in<br>
&gt;&gt; SmbFile.doConnect():<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0String hostName =3D getServerWith=
Dfs();<br>
&gt;&gt;<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0tree.inDomainDfs =3D dfs.resolve(=
hostName, tree.share, null,<br>
auth)<br>
&gt;&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0!=3D<br>
&gt;&gt; null;<br>
&gt;&gt;<br>
&gt;&gt; In this code, we are getting the DFS resolver (which might be the<=
br>
domain<br>
&gt;&gt; server) as the hostName, and asking it to resolve our share.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Basically what this new code is saying is that:<br>
&gt;&gt;<br>
&gt;&gt; - in the case where the transport has closed (ie, because of a tim=
eout<br>
or<br>
&gt;&gt; TCP close on the DFS server side) reconnect to the DFS domain serv=
er in<br>
&gt;&gt; order to resolve a share&#39;s DFS server.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; I can imagine a case where this doesn&#39;t work--if we have multi=
ple<br>
levels<br>
&gt;&gt; of<br>
&gt;&gt; DFS redirection, where the domain server cannot redirect the clien=
t to<br>
a<br>
&gt;&gt; deep subdirectory.=C2=A0 But, I don&#39;t even know if this is pos=
sible in DFS.<br>
&gt;&gt; If<br>
&gt;&gt; it is, then at least this solution removes the top level case and<=
br>
&gt;&gt; identifies<br>
&gt;&gt; the problem, which would require walking down the DFS resolution p=
ath<br>
to<br>
&gt;&gt; resolve the actual file server.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Conrad Herrmann<br>
&gt;&gt;<br>
&gt;&gt; Primdaesk, Inc.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; Hi,<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; I encountered a NullpointerException similar to<br>
&gt;&gt;<br>
&gt;&gt;&gt; <a href=3D"https://lists.samba.org/archive/jcifs/2012-January/=
009856.html" rel=3D"noreferrer" target=3D"_blank">https://lists.samba.org/a=
rchive/jcifs/2012-January/009856.html</a> - at<br>
&gt;&gt;<br>
&gt;&gt;&gt; least the stack traces are similar.<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; My Environment (Client side):<br>
&gt;&gt;<br>
&gt;&gt;&gt; - jcifs 1.3.18<br>
&gt;&gt;<br>
&gt;&gt;&gt; - IBM JDK 7<br>
&gt;&gt;<br>
&gt;&gt;&gt; - AIX 7.1<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; The NPE occured in a (in-house) plugin for the Jenkins build s=
erver.<br>
In<br>
&gt;&gt;<br>
&gt;&gt;&gt; this system, JCIFs is used to recursively copy files from a Wi=
ndows<br>
&gt;&gt;<br>
&gt;&gt;&gt; share to an AIX machine.<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; Re-running a build shortly after it finished triggered the NPE=
.<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; After some debugging, it seems to me like the SmbFile=E2=80=99=
s underlying<br>
&gt;&gt;<br>
&gt;&gt;&gt; transport is closed (by timeout), and when SmbFile.resolveDfs =
is<br>
called,<br>
&gt;&gt;<br>
&gt;&gt;&gt; the transport is not reconnected (unlike, for example, later i=
n<br>
&gt;&gt;<br>
&gt;&gt;&gt; SmbFile.resolve, or in SmbSession.getChallenge).<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; I was able to reproduce the NPE during debugging using the fol=
lowing<br>
&gt;&gt;<br>
&gt;&gt;&gt; steps:<br>
&gt;&gt;<br>
&gt;&gt;&gt; - Trigger a build (recursively copying from a CIFS DFS tree)<b=
r>
&gt;&gt;<br>
&gt;&gt;&gt; - Wait until the transport objects disconnect by timeout (trac=
ked by<br>
&gt;&gt;<br>
&gt;&gt;&gt; breakpoint)<br>
&gt;&gt;<br>
&gt;&gt;&gt; - Retrigger the build (recursively copying the same directory<=
br>
structure)<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; The Jenkins plugin usually runs the second JCIFS copy operatio=
n in the<br>
&gt;&gt;<br>
&gt;&gt;&gt; same thread than the first (though that&#39;s not guaranteed).=
<br>
&gt;&gt;<br>
&gt;&gt;&gt; Each run uses a new SmbFile object.<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; Am I missing something (like some close operation on SmbFile)?=
<br>
&gt;&gt;<br>
&gt;&gt;&gt; Is this a known error?<br>
&gt;&gt;<br>
&gt;&gt;&gt; Can I do something to fix it?<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; Best regards,<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; Martin<br>
&gt;&gt;<br>
&gt;&gt;&gt;<br>
</div></div></blockquote></div><br></div>

--20cf3079b68832a19e05188f8705--