Same issue as in bug 2940317. Version 3.2.0 still fails to call serviceResolved reliably.
On a side note: requestServiceInfo is blocking at least 200ms. Why does it block at all and why can't it be called in the serviceAdded event handler (fails to resolve silently)?
I've attached a test case that fails most of the time on Ubuntu 10.04:
$ avahi-publish-service X _test._tcp 123 &
$ while true; do java -cp .:jmdns.jar JmDNSResolveBug 2>/dev/null; done
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
I do not have access to an Ubuntu box, Before we go for another round of searching could you tell me if the unit tests run on your box?
On the asynchronous thing, I am not sure what the problem is. There are 2 APIs, one based on event if fully asynchronous and the other one based on direct calls is synchronous. requestServiceInfo is meant to be synchronous I agree that the 200 ms is a bug and I will have a look at this, we should not wait if we already have the info.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Hi Pierre, sorry for the delay.
I was just wondering how to kick off the resolved event without blocking any thread. I thought requestServiceInfo was meant to be used for this and getServiceInfo as the synchronous counterpart.
Now the unit tests don't run through actually, because registerService hangs forever.
Let start by the beginning. Get the unit test to run. Then we will understand why the service does not get resolved.
In the test.setup() there is a boolean log can you set it to true and attach the log result?
I suspect that if registerService does not return it is because either the DNS or the info is never announced. This would severely impact the behavior of JmDNS.
As for the API I was never sure why there are 2. I like your idea but I am afraid it would break existing code and we would get a lot of bug reports. But it is worth considering.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
I'm using the SVN version just for safety now. registryService hangs on
Thread [main] (Suspended)
ReentrantLock$NonfairSync(AbstractQueuedSynchronizer).release(int) line: 1262
HostInfo$HostInfoState(ReentrantLock).unlock() line: 459
HostInfo$HostInfoState(DNSStatefulObject$DefaultImplementation).waitForAnnounced(long) line: 319
HostInfo.waitForAnnounced(long) line: 413
JmDNSImpl.waitForAnnounced(long) line: 478
JmDNSImpl.registerService(ServiceInfo) line: 895
JmDNSTest.testRegisterService() line: 94
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 57
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43
Method.invoke(Object, Object...) line: 616
FrameworkMethod$1.runReflectiveCall() line: 44
FrameworkMethod$1(ReflectiveCallable).run() line: 15
FrameworkMethod.invokeExplosively(Object, Object...) line: 41
InvokeMethod.evaluate() line: 20
RunBefores.evaluate() line: 28
BlockJUnit4ClassRunner.runChild(FrameworkMethod, RunNotifier) line: 76
BlockJUnit4ClassRunner.runChild(Object, RunNotifier) line: 50
ParentRunner$3.run() line: 193
ParentRunner$1.schedule(Runnable) line: 52
BlockJUnit4ClassRunner(ParentRunner<T>).runChildren(RunNotifier) line: 191
ParentRunner<T>.access$000(ParentRunner, RunNotifier) line: 42
ParentRunner$2.evaluate() line: 184
BlockJUnit4ClassRunner(ParentRunner<T>).run(RunNotifier) line: 236
JUnit4TestClassReference(JUnit4TestReference).run(TestExecution) line: 46
TestExecution.run(ITestReference[]) line: 38
RemoteTestRunner.runTests(String[], String, TestExecution) line: 467
RemoteTestRunner.runTests(TestExecution) line: 683
RemoteTestRunner.run() line: 390
RemoteTestRunner.main(String[]) line: 197
because the HostInfoState isn't changing from "ANNOUNCING_2".
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
I'm sorry, the test suite issue is related to the way Debian/Ubuntu resolve the local hostname. If I create all JmDNS instances on a local IP, the suite runs fine. Your assumption must have been correct.
Could we improve out unit test so that they run correctly out of the box? This would save us a lot of grief.
Could it be that we have the same issue in your test?
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
The unit test problem is probably related to this comment
// [PJYF Oct 14 2004] Why do we disallow the loopback address ?
as the hostname on debian based distros is usually resolved to 127.0.1.1, which is a loopback adress too.
However, the test case runs regardless and still fails with a network ip passed to JmDNS.create.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
The bug occurs on Windows Vista too.
PJYF is myself.
I think we should allow the loopback although in normal use this is probably non sensical. I may add a property so that we can get the unit test to run on Ubuntu. You are not the first one to have the problem.
Just to be sure that I understand the issue correctly could you try the same setup but run the JmDNS browser. You should see your service resolved.
Why call:
ServiceInfo info = event.getDNS().getServiceInfo(event.getType(), event.getName());
On a service added event this will likely result in a null. On a service resolved even you should access the info with even.getInfo() which should give you the resolved info.
Ok the test as written cannot work. The issue is that the serviceAdded method never surrender execution so JmDNS cannot call the resolve method. Have a look at the revised code that should work.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
The browser is working, but it doesn't depend on serviceResolved. It stalls the AWT event loop btw.
I need the service details, but can't block the UI event thread. So I have to wait for serviceResolved to be called, but that will only happen if I request (or get) the service info.
What I wanted to do:
void serviceAdded(ServiceEvent event) {
ServiceInfo info = event.getDNS().getServiceInfo(event.getType(), event.getName());
handleResolvedService(info);
}
or
void serviceAdded(ServiceEvent event) {
invokeInSomeOtherThread(new Runnable() { public void run() {
event.getDNS().requestServiceInfo(event.getType(), event.getName(), );
}});
}
void serviceResolved(ServiceEvent event) {
handleResolvedService(event.getInfo());
}
Both these snippets will not work! The first one won't work at all and just silently return null after a few seconds, the second version will work only sometimes (see this bug report). So to do this reliably I have to do the blocking getServiceInfo call in some other thread and call handleResolvedService from there too.
You are trying too hard. JmDNS will do the work for you. If the only thing you are interested is the service resolved ignore the service added and only use serviceResolved();
The service resolution will occurs independently of the call to requestServiceInfo().
If you like to submit an improved browser :)
To be very clear just do:
void serviceResolved(ServiceEvent event) {
handleResolvedService(event.getInfo());
}
and forget the serviceAdded() This is only really useful if you present a list to the user and don't care that the service is resolved, like the browser.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Then the bug report should be labeled: serviceResolved is never called, although serviceAdded is.
The test case works as executor.submit will execute the getServiceInfo call in another thread. serviceAdded returns almost immediately.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Yeah that was what I tried first :). However serviceResolved never gets called, so I tried requesting a resolver update.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
The DiscoverServices example never prints 'Service resolved' either :(.
I am a bit puzzled I have tried that on MacOSX which is the machine I have in front of me and it run very reliably.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
It works 50/50 on Ubuntu and Windows. I'm pretty certain it's a race condition which makes debugging the problem really hard.
View and moderate all "bugs Discussion" comments posted by this user
Mark all as spam, and block user from posting to "Bugs"
Does the DiscoverServices work for you? I get 'Service added' and 'Service removed' but never a 'Service resolved'.
try with the version I just submitted