Despite being called a "factory", the instance you get from JmmDNS.Factory.getInstance() does not actually return a new instance.
This causes a problem if you have two callers in the same JVM which both want to create a JmmDNS and later plan to close it. The first caller will call close() and then any attempts by the second caller to use the service will result in failure.
The workaround is to just create a new JmmDNSImpl() each time you want one and avoid the factory entirely. I would recommend this for anyone writing code which might be used as a library, because you don't know what other libraries might be running in the same JVM which are also using JmDNS.
As for how to fix it - sharing an instance is probably fine, but what you should do is track the references. I would do it something like this:
(1) Still maintain a single instance but never pass it directly to anybody.
(2) Each time getInstance() is called, create a new instance of JmmDNS which is actually a thin wrapper around the real thing.
(3) When close() is called on this wrapper, record that close() has been called and decrement the reference count.
(4) If the reference count has reached 0, close the real JmmDNSImpl.
(5) If close() has already been called on the wrapper, ignore any subsequent calls to close() (if you don't do this, you can poison someone else's references by calling close() on your own one.)