Issues with Discovery in Java

6 posts / 0 new
Last post
Offline
Last seen: 9 years 10 months ago
Joined: 05/15/2014
Posts: 3
Issues with Discovery in Java

I am working with Open Community DDS and running a C++ application with 2 publishers. I am writing a Java application that will discover the available topics on a domain. I have read and am using sample code from the following post: http://community.rti.com/content/forum-topic/listening-all-dds-messages-being-published

If I have the C++ application running and then start the Java application, even though it is using a WaitSet with Infinite Timeout, no printout appears after minutes of waiting. Other times when I start the Java application 2nd the publishers are discovered immediately.

When I start the "MonitorDicoveredTypes" application first and then start my C++ application, the Java application spits out the information about 2 publishers.

Throughout my testing I have rtiddsspy running and it is always displaying the 2 publishers from the C++ application.

Why does rtiddsspy so consistently discover the publishers while the Java ("MonitorDicoveredTypes") application does not?

Some additional details:

All applications running on same Windows 7 PC. NDDS 5.0.0.

For a simple test I used the "Hello Simple" example from the ndds5.0.0\example\CPP\ directory and the Java class is attached to this post.


It appears I am looking to address the same issue as the following user:

http://community.rti.com/comment/1502#comment-1502

AttachmentSize
File monitordicoveredtypes.java14.72 KB
Offline
Last seen: 5 days 16 hours ago
Joined: 06/13/2013
Posts: 17

You are on the right track with your application. The key is that you create all the entities before enabling the participant so you don't miss any topic which might get discioered after the participant is created but before you have your waitsets ready. You do this in your code as follow:

DomainParticipantFactory factory = DomainParticipantFactory.get_instance();
DomainParticipantFactoryQos factoryQos = new DomainParticipantFactoryQos();

// This instructs the DomainParticipantFactory to not enable the DomainParticipant
// entities it creates automatically. This is needed so that we have a chance to
// retrieve the builtin data-readers before the participant starts receiving
// discovery data. Later it is explained why this is needed
factoryQos.entity_factory.autoenable_created_entities = false;

And then later you enable the participant:

try {
participant.enable();
} catch ( Exception e) {
String lastStartError = "Error enabling the DDS domain. Common causes are:"
+ "\n - Lack of a network. E.g disconected wireless."
+ "\n - A network interface that does not bind multicast addresses. In some platforms enabling using the TUN interface "
+ "\n for (Open)VPN causes this. If this is your situation try configure (Open)VPN to use TAP instead.";

System.out.println(lastStartError);
return false;
}

However the step you are missing is after changing the factory QoS you have to set the factory QoS. You get the QoS modify it but never set it. What is missing is the factory.set_qos(factoryQos); after you modify the QoS. So the code should look as follow:

DomainParticipantFactory factory = DomainParticipantFactory.get_instance();
DomainParticipantFactoryQos factoryQos = new DomainParticipantFactoryQos();

// This instructs the DomainParticipantFactory to not enable the DomainParticipant
// entities it creates automatically. This is needed so that we have a chance to
// retrieve the builtin data-readers before the participant starts receiving
// discovery data. Later it is explained why this is needed
factoryQos.entity_factory.autoenable_created_entities = false;

factory.set_qos(factoryQos);

 

Please let me know if that worked for you. 

 

Andre

 

 

 

Offline
Last seen: 9 years 10 months ago
Joined: 05/15/2014
Posts: 3

That worked.


Thank you Andre.

Offline
Last seen: 5 years 8 months ago
Joined: 01/31/2011
Posts: 37

Just one quick comment - it's best to call

factory.get_qos(factoryQos)

Before you modify the factory qos. So the sequence goes:

  1. get the factory qos
  2. set the autoenable_created_entities property to false
  3. set the factory qos
Offline
Last seen: 9 years 10 months ago
Joined: 05/15/2014
Posts: 3

I am trying to change the initial_peers field of the ParticipantQoS.discovery class but it appears the variable is final.

This seem different from the C++ version as there I would use the following code to set my initial peers:

/* set new initial peer for sending discovery information */ 
participant_qos.discovery.initial_peers.maximum(3); 
participant_qos.discovery.initial_peers.length(3); 
participant_qos.discovery.initial_peers[0] = DDS_String_dup("129.168.0.1"); 
participant_qos.discovery.initial_peers[1] = DDS_String_dup("4@builtin.udpv4://127.0.0.1"); 
participant_qos.discovery.initial_peers[2] = DDS_String_dup("builtin.shmem://");
participant_qos.discovery.multicast_receive_addresses.length(0);
It also appears the transport fields is also made final.
 
How would I accomplish this in Java?
Offline
Last seen: 5 years 8 months ago
Joined: 01/31/2011
Posts: 37

The discovery peers list is a StringSequence, and these behave more like Java collections in our Java API. The Java equivalent of the C++ code above would be:

participant_qos.discovery.initial_peers.add("192.168.0.1");
        participant_qos.discovery.initial_peers.add("4@builtin.udpv4://127.0.0.1");
participant_qos.discovery.initial_peers.add("builtin.shmem://");            participant_qos.discovery.multicast_receive_addresses.clear();