[jcifs] bugs in JCIFS 1.2.9
Michael B Allen
mba2000 at ioplex.com
Fri Nov 24 16:24:28 GMT 2006
The following thread should cause the writer thread to exit.
2139 try {
2140 copyTo0( dest, b, bsize, w, req, resp );
2141 } finally {
2142 w.write( null, -1, null, 0 );
2143 }
I cannot reproduce this problem. I think you are confusing the writer
thread with the Transport threads. You will need to get a thread dump
to verify this.
Run the attached example like:
$ java -Djcifs.properties=../miallen.prp CopyToTest smb://ts0.win.net/tmp/bogus.txt smb://nano.foo.net/pub/bogus.txt
jcifs.smb.SmbException: The system cannot find the file specified.
at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:511)
at jcifs.smb.SmbTransport.send(SmbTransport.java:588)
at jcifs.smb.SmbSession.send(SmbSession.java:239)
at jcifs.smb.SmbTree.send(SmbTree.java:109)
at jcifs.smb.SmbFile.send(SmbFile.java:690)
at jcifs.smb.SmbFile.queryPath(SmbFile.java:1202)
at jcifs.smb.SmbFile.copyTo0(SmbFile.java:1950)
at jcifs.smb.SmbFile.copyTo(SmbFile.java:2140)
at CopyToTest.run(CopyToTest.java:17)
<get a thread dump [1]>
Full thread dump Java HotSpot(TM) Client VM (1.4.2_08-b03 mixed mode):
"Transport2" daemon prio=1 tid=0x093bbae8 nid=0x3eea runnable [4be3000..4be4228]
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at jcifs.util.transport.Transport.readn(Transport.java:29)
at jcifs.smb.SmbTransport.peekKey(SmbTransport.java:352)
at jcifs.util.transport.Transport.loop(Transport.java:100)
at jcifs.util.transport.Transport.run(Transport.java:261)
at java.lang.Thread.run(Thread.java:534)
"Transport1" daemon prio=1 tid=0x093b77d0 nid=0x3eea runnable [2ef6000..2ef7228]
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at jcifs.util.transport.Transport.readn(Transport.java:29)
at jcifs.smb.SmbTransport.peekKey(SmbTransport.java:352)
at jcifs.util.transport.Transport.loop(Transport.java:100)
at jcifs.util.transport.Transport.run(Transport.java:261)
at java.lang.Thread.run(Thread.java:534)
"Signal Dispatcher" daemon prio=1 tid=0x0925d8d8 nid=0x3eea waiting on condition [0..0]
"Finalizer" daemon prio=1 tid=0x09248e38 nid=0x3eea in Object.wait() [5a6000..5a6228]
at java.lang.Object.wait(Native Method)
- waiting on <0xae3573f0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <0xae3573f0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=1 tid=0x09248290 nid=0x3eea in Object.wait() [4eb000..4eb228]
at java.lang.Object.wait(Native Method)
- waiting on <0xae357290> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:429)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115)
- locked <0xae357290> (a java.lang.ref.Reference$Lock)
"main" prio=1 tid=0x092129a0 nid=0x3eea waiting on condition [bff37000..bff3729c]
at java.lang.Thread.sleep(Native Method)
at CopyToTest.main(CopyToTest.java:27)
"VM Thread" prio=1 tid=0x09247030 nid=0x3eea runnable
"VM Periodic Task Thread" prio=1 tid=0x092600d8 nid=0x3eea waiting on condition
"Suspend Checker Thread" prio=1 tid=0x0925cf20 nid=0x3eea runnable
You can see above there is no "JCIFS-WriterThread" listed.
Now wait 20 seconds for the Transport threads to exit and do a thread
dump again:
Full thread dump Java HotSpot(TM) Client VM (1.4.2_08-b03 mixed mode):
"Signal Dispatcher" daemon prio=1 tid=0x0925d8d8 nid=0x3eea runnable [0..0]
"Finalizer" daemon prio=1 tid=0x09248e38 nid=0x3eea in Object.wait() [5a6000..5a6228]
at java.lang.Object.wait(Native Method)
- waiting on <0xae3573f0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:111)
- locked <0xae3573f0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:127)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)
"Reference Handler" daemon prio=1 tid=0x09248290 nid=0x3eea in Object.wait() [4eb000..4eb228]
at java.lang.Object.wait(Native Method)
- waiting on <0xae357290> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:429)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:115)
- locked <0xae357290> (a java.lang.ref.Reference$Lock)
"main" prio=1 tid=0x092129a0 nid=0x3eea waiting on condition [bff37000..bff3729c]
at java.lang.Thread.sleep(Native Method)
at CopyToTest.main(CopyToTest.java:27)
"VM Thread" prio=1 tid=0x09247030 nid=0x3eea runnable
"VM Periodic Task Thread" prio=1 tid=0x092600d8 nid=0x3eea waiting on condition
"Suspend Checker Thread" prio=1 tid=0x0925cf20 nid=0x3eea runnable
Now you can see only VM threads are left.
AFAICT everything is working perfectly.
Or just try to add a 20 second sleep to your test and you'll see the
Transport threads exit. You can make them close quicker by reducing
jcifs.smb.client.soTimeout.
Mike
[1] To get a thread dump on Windows, run your program on the console
and press <ctrl><break> (on Unix it's <ctrl>\).
On Fri, 24 Nov 2006 09:42:37 +0100
"Tim Struyf" <tim.struyf at roots.be> wrote:
> Dear,
>
>
>
> Here is a stacktrace,
>
> If you get this exception, then the writer thread won't get closed
> correctly.
>
>
>
>
>
> jcifs.smb.SmbException: The system cannot find the file specified.
>
> at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:511)
>
> at jcifs.smb.SmbTransport.send(SmbTransport.java:588)
>
> at jcifs.smb.SmbSession.send(SmbSession.java:239)
>
> at jcifs.smb.SmbTree.send(SmbTree.java:109)
>
> at jcifs.smb.SmbFile.send(SmbFile.java:690)
>
> at jcifs.smb.SmbFile.queryPath(SmbFile.java:1202)
>
> at jcifs.smb.SmbFile.copyTo0(SmbFile.java:1950)
>
> at jcifs.smb.SmbFile.copyTo(SmbFile.java:2140)
>
> at jcifs.test.JCifsTest.testCopy(JCifsTest.java:41)
>
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.jav
> a:39)
>
> at
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor
> Impl.java:25)
>
> at java.lang.reflect.Method.invoke(Method.java:324)
>
> at junit.framework.TestCase.runTest(TestCase.java:154)
>
> at junit.framework.TestCase.runBare(TestCase.java:127)
>
> at junit.framework.TestResult$1.protect(TestResult.java:106)
>
> at junit.framework.TestResult.runProtected(TestResult.java:124)
>
> at junit.framework.TestResult.run(TestResult.java:109)
>
> at junit.framework.TestCase.run(TestCase.java:118)
>
> at junit.framework.TestSuite.runTest(TestSuite.java:208)
>
> at junit.framework.TestSuite.run(TestSuite.java:203)
>
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTe
> stRunner.java:478)
>
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRun
> ner.java:344)
>
> at
> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRu
> nner.java:196)
>
> jcifs.smb.SmbException: The system cannot find the file specified.
>
> at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:511)
>
> at jcifs.smb.SmbTransport.send(SmbTransport.java:588)
>
> at jcifs.smb.SmbSession.send(SmbSession.java:239)
>
> at jcifs.smb.SmbTree.send(SmbTree.java:109)
>
> at jcifs.smb.SmbFile.send(SmbFile.java:690)
>
>
>
>
>
> You will get this when you put up a share, and try to copy a file that
> does NOT exist from this share to another share.
>
> The JCIFS writerthreads should be closed when such a thing happens. In
> the current version, the writer threads aren't closed, so the test case
> below will cause 1000 writer threads to be locked...
>
>
>
>
>
> for(int i = 0; i < 1000; i++) {
>
> try {
>
> SmbFile file = JCifsUtil.getSmbFileFor(
> "myComputer/someShare/doesNotExist.txt" );
>
> SmbFile to = JCifsUtil.getSmbFileFor(
> "anotherComputer/someShare/doesNotExist.txt");
>
> file.copyTo(to);
>
> } catch (Exception e) {
>
> e.printStackTrace();
>
> }
>
> /* put breakpoint up here, you will see 1000 writer threads in
> wait state */
>
> }
>
>
>
> JCifsUtil is just a small class which returns an SmbFile for the given
> input.
>
>
>
> regards,
>
> Tim
>
>
>
> Tim Struyf
>
> Consultant,
>
>
>
> Roots Software
>
> Oudestraat 113 * 2630 Aartselaar * Belgium
>
> Email: tim.struyf at roots.be
>
> http://www.roots.be
>
>
>
> -----Original Message-----
> From: Michael B Allen [mailto:mba2000 at ioplex.com]
> Sent: dinsdag 21 november 2006 17:56
> To: Tim Struyf
> Cc: jcifs at lists.samba.org; contact! Support
> Subject: Re: [jcifs] bugs in JCIFS 1.2.9
>
>
>
> Using interrupt should not be necessary. I was not able to reproduce
>
> this issue. If a WriterThread is blocked trying to write than you need
>
> to figure out why. What is the Exception that is being thrown in your
>
> catch that issues the interrupt?
>
>
>
> If there is a bug in the logic then I would be happy to fix that but I
>
> fail to see WHY you think interrupt() should be necessary.
>
>
>
> Can you provide a thread dump?
>
>
>
> Mike
>
>
>
> On Wed, 15 Nov 2006 15:35:36 +0100
>
> "Tim Struyf" <tim.struyf at roots.be> wrote:
>
>
>
> > Dear,
>
> >
>
> > This issue isnt fixed in JCIFS 1.2.10...
>
> > I still see a lot of writer threads that stay in their locked state in
> the new version...
>
> >
>
> > I thinkt the w.interrupt is realy required to fix this issue...
>
> >
>
> > see attached screenshot
>
> >
>
> > regards,
>
> > Tim
>
> >
>
> > ________________________________
>
> >
>
> > From: Michael B Allen [mailto:mba2000 at ioplex.com]
>
> > Sent: Mon 13/11/2006 5:40 PM
>
> > To: Tim Struyf; jcifs at lists.samba.org; contact! Support
>
> > Subject: Re: [jcifs] bugs in JCIFS 1.2.9
>
> >
>
> >
>
> >
>
> > This has been fixed. If the copyTo0 fails a finally has been added to
>
> > guarantee files are closed. Another finally has been added to copyTo()
>
> > that guarantees that the stop write signals the WriterThread to wake
> up
>
> > and exit (if the WriterThread is stuck trying to read this will have
> no
>
> > effect, it does not use interrupt()).
>
> >
>
> > Mike
>
> >
>
> > On Wed, 8 Nov 2006 13:03:42 -0500
>
> > Michael B Allen <mba2000 at ioplex.com> wrote:
>
> >
>
> > > Yes, I believe this is all the same bug someone reported before. The
>
> > > bug is because of a big try catch added to SmbFile.copyTo0 during
> some
>
> > > debugging. Try to remove/move the try catch to look like the below:
>
> > > And please let me know if it works. I'm going to do an update soon.
>
> > >
>
> > > 1972 }
>
> > > 1973 } else {
>
> > > 1974 int off;
>
> > > 1975
>
> > > 1976 try {
>
> > > 1977 open( SmbFile.O_RDONLY, 0, ATTR_NORMAL, 0 );
>
> > > 1978 try {
>
> > > ....
>
> > > 2022 dest.send( new Trans2SetFileInformation(
>
> > > 2023 dest.fid, attributes, createTime,
> lastModified ),
>
> > > 2024 new
> Trans2SetFileInformationResponse() );
>
> > > 2025 dest.close( 0L );
>
> > > 2026 } catch( Exception ex ) {
>
> > > 2027 if( log.level > 1 )
>
> > > 2028 ex.printStackTrace( log );
>
> > > 2029 } finally { <<---- important to always close!
>
> > > 2030 close();
>
> > > 2031 }
>
> > > 2032 }
>
> > > 2033 }
>
> > > 2034 /**
>
> > >
>
> > >
>
> > > On Wed, 8 Nov 2006 17:00:18 +0100
>
> > > "Tim Struyf" <tim.struyf at roots.be> wrote:
>
> > >
>
> > > > Dear,
>
> > > >
>
> > > >
>
> > > >
>
> > > > I found a bug in JCIFS 1.2.9
>
> > > >
>
> > > >
>
> > > >
>
> > > > Apparently when trying to copy a file that does not exist the
>
> > > > writerthread isn't closed.
>
> > > >
>
> > > > Thus causing problems with a lot of writerthreads that are and
> remain in
>
> > > > the "wait" state
>
> > > >
>
> > > >
>
> > > >
>
> > > > For example if you execute this testcase with version 1.2.9 you
> will get
>
> > > > 1000 writer threads in the "wait" state
>
> > > >
>
> > > > Important is that you have a share and try to open a file that
> does not
>
> > > > exist, you will get a stacktrace printed in your console ... but
> the
>
> > > > writer thread stays open...
>
> > > >
>
> > > >
>
> > > >
>
> > > > public class JCifsTest extends TestCase {
>
> > > >
>
> > > > public void testCopy() {
>
> > > >
>
> > > > for(int i = 0; i < 1000; i++) {
>
> > > >
>
> > > > try {
>
> > > >
>
> > > > SmbFile file
>
> > > > = JCifsUtil.getSmbFileFor(
> "myComputer/someShare/fileDoesNotExist.txt"
>
> > > > );
>
> > > >
>
> > > > SmbFile to
>
> > > > = JCifsUtil.getSmbFileFor(
> "myComputer/someShare/fileDoesNotExist.txt");
>
> > > >
>
> > > > file.copyTo(to);
>
> > > >
>
> > > > } catch (Exception e) {
>
> > > >
>
> > > >
> e.printStackTrace();
>
> > > >
>
> > > > }
>
> > > >
>
> > > > }
>
> > > >
>
> > > > //put a breakpoint up here and see... 1000
>
> > > > writer threads waiting...
>
> > > >
>
> > > > System.out.println("boom!");
>
> > > >
>
> > > > }
>
> > > >
>
> > > > }
>
> > > >
>
> > > >
>
> > > >
>
> > > > I fixed this by adding a try catch clause in the copyTo method in
>
> > > > SmbFile.java
>
> > > >
>
> > > >
>
> > > >
>
> > > > /** copy to method.... **/
>
> > > >
>
> > > >
>
> > > >
>
> > > > w = new WriterThread();
>
> > > >
>
> > > > w.setDaemon( true );
>
> > > >
>
> > > > w.start();
>
> > > >
>
> > > > //added a try catch block
>
> > > >
>
> > > > try {
>
> > > >
>
> > > > /* Downgrade one transport to the lower of the
>
> > > > negotiated buffer sizes
>
> > > >
>
> > > > * so we can just send whatever is received.
>
> > > >
>
> > > > */
>
> > > >
>
> > > >
>
> > > >
>
> > > > SmbTransport t1 = tree.session.transport;
>
> > > >
>
> > > > SmbTransport t2 = dest.tree.session.transport;
>
> > > >
>
> > > >
>
> > > >
>
> > > > if( t1.snd_buf_size < t2.snd_buf_size ) {
>
> > > >
>
> > > > t2.snd_buf_size = t1.snd_buf_size;
>
> > > >
>
> > > > } else {
>
> > > >
>
> > > > t1.snd_buf_size = t2.snd_buf_size;
>
> > > >
>
> > > > }
>
> > > >
>
> > > >
>
> > > >
>
> > > > bsize = Math.min( t1.rcv_buf_size - 70,
>
> > > > t1.snd_buf_size - 70 );
>
> > > >
>
> > > > b = new byte[2][bsize];
>
> > > >
>
> > > >
>
> > > >
>
> > > > copyTo0( dest, b, bsize, w, req, resp );
>
> > > >
>
> > > > w.write( null, -1, null, 0 );
>
> > > >
>
> > > > } catch (Exception e ){
>
> > > >
>
> > > > //stop the writer thread! If we get an exception
>
> > > >
>
> > > > e.printStackTrace();
>
> > > >
>
> > > > w.interrupt();
>
> > > >
>
> > > > }
>
> > > >
>
> > > >
>
> > > >
>
> > > >
>
> > > >
>
> > > > Another bug was already posted here.
>
> > > >
>
> > > > If you try to copy a file to a share on which you don't have
> access
>
> > > > rights, this fails but the writer threads don't close... also the
> source
>
> > > > file you are copying from cant be deleted... because its in use...
> (by
>
> > > > the writerthread that's locked...)
>
> > > >
>
> > > >
>
> > > >
>
> > > > public void testCopyAndDelete() throws SmbException {
>
> > > >
>
> > > > for(int i = 0; i < 1000; i++) {
>
> > > >
>
> > > > try {
>
> > > >
>
> > > > SmbFile file
> =
>
> > > > JCifsUtil.getSmbFileFor( "myComputer/myShare/someFile.txt" );
>
> > > >
>
> > > >
>
> > > > System.out.println(file.getUncPath() + " exists: " +
> file.exists());
>
> > > >
>
> > > > SmbFile to
>
> > > > = JCifsUtil.getSmbFileFor(
>
> > > > "myComputer/ShareOnWhichIDontHaveAccessRights/someFile.txt");
>
> > > >
>
> > > >
>
> > > > System.out.println(to.getUncPath() + " exists: " +
> to.exists());
>
> > > >
>
> > > > file.copyTo( to );
>
> > > >
>
> > > > file.delete();
>
> > > >
>
> > > > } catch (Exception e) {
>
> > > >
>
> > > >
> e.printStackTrace();
>
> > > >
>
> > > > }
>
> > > >
>
> > > > }
>
> > > >
>
> > > > }
>
> > > >
>
> > > >
>
> > > >
>
> > > > In version 1.2.9 of JCIFS this code will cause the errors
> described
>
> > > > above, a lot of writer threads that are locked + files that are in
> use,
>
> > > > and cant be deleted...
>
> > > >
>
> > > > I fixed this by changing the copyTo0 method in SmbFile.java
>
> > > >
>
> > > >
>
> > > >
>
> > > >
>
> > > >
>
> > > > dest.send( new
>
> > > > Trans2SetFileInformation(dest.fid, attributes, createTime,
> lastModified
>
> > > > ), new Trans2SetFileInformationResponse() );
>
> > > >
>
> > > > dest.close( 0L );
>
> > > >
>
> > > > } catch( Exception ex ) {
>
> > > >
>
> > > > //stop the
> writerthreads
>
> > > >
>
> > > > w.interrupt();
>
> > > >
>
> > > > if( log.level > 1
> )
>
> > > >
>
> > > >
>
> > > > ex.printStackTrace( log );
>
> > > >
>
> > > > } finally {
>
> > > >
>
> > > > //added a finally
> clause
>
> > > >
>
> > > > close();
>
> > > >
>
> > > > }
>
> > > >
>
> > > > Best regards,
>
> > > >
>
> > > > Tim
>
> > > >
>
> > > > groetjes,
>
> > > >
>
> > > > Tim Struyf
>
> > > > Consultant,
>
> > > >
>
> > > > Roots Software
>
> > > > Oudestraat 113 * 2630 Aartselaar * Belgium
>
> > > > Phone + 32 3 870 71 11 * Fax + 32 3 870 71 19
>
> > > > Email: tim.struyf at roots.be <mailto:tim.struyf at roots.be>
>
> > > > http://www.roots.be
>
> > > >
>
> > > >
>
> > > >
>
> > > >
>
> > >
>
> > >
>
> > > --
>
> > > Michael B Allen
>
> > > PHP Active Directory SSO
>
> > > http://www.ioplex.com/
>
> > >
>
> >
>
> >
>
> > --
>
> > Michael B Allen
>
> > PHP Active Directory SSO
>
> > http://www.ioplex.com/
>
> >
>
> >
>
> >
>
>
>
>
>
> --
>
> Michael B Allen
>
> PHP Active Directory SSO
>
> http://www.ioplex.com/
>
>
--
Michael B Allen
PHP Active Directory SSO
http://www.ioplex.com/
More information about the jcifs
mailing list