Unknown Source error

20 posts / 0 new
Last post
Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23
Unknown Source error

I am getting an error when I call the DomainParticipant enable() method.  Here are some lines of code in Java that I am using.

final DomainParticipant = participant;

DomainParticipantFactoryQos factoryQos = new DomainParticipantFactoryQos();

DomainParticipantFactory.The ParticipantFactory.get_qos( factoryQos );

factoryQos.entity_factory.autoenable_created_entities = false;

DomainParticipantFactory.The ParticipantFactory.set_qos( factoryQos );

participant = DomainParticipantFactory.get_instance().create_participant( 14, DomainParticipantFactory.PARTICIPANT_QOS_DEFAULT, null, 0 );

participant.enable();

The code blows up here.  Here is the first part of the stack trace:

com.rti.dds.intrastructure.RETCODE_ERROR

            at com.rti.dds.util.Utilities.rethrow(Unknown Source)

            at com.rti.dds.intrastructure.EntityImpl.enable(Unknown Source)

            . . .

Any ideas what this error means?

Thanks.

 

Organization:
Gerardo Pardo's picture
Offline
Last seen: 1 week 2 days ago
Joined: 06/02/2010
Posts: 602

Hi,

The line:

 final DomainParticipant = participant;

 looks like a copy-paste error as it does not compile.

Other than that the code you have seems fine. I created similar code by modifying the Java example that rtiddsgen creates and it runs with no errors.

You could add the following line to the beginning of your program and then re-run it:

        Logger.get_instance().set_verbosity(LogVerbosity.NDDS_CONFIG_LOG_VERBOSITY_STATUS_LOCAL);

This will enable a high level of verbosity messages. Perhaps the printouts it produces will shed some light on what the error is...

Gerardo

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Thanks Gerardo,

You are correct.  The "=" sign should not be there.  The line should be:

      final DomainParticipant participant;

 

I should also add that the problem occurs as I add more "participants" (i.e. more domains).  It could be a resource problem, and that could be why RTI DDS is seeing this participant as an Unknown Source - (not sure???).

 

I don't have any compile problems.  The code even runs a little, but this participant does not get enabled. I am still not sure why.

 

 

 

 

Gerardo Pardo's picture
Offline
Last seen: 1 week 2 days ago
Joined: 06/02/2010
Posts: 602

Hello Herb,

Sorry, I did not mean compile errors. I meant that I executed the Java code you provided and it run, enabling the DomainParticipant and sending messages without generating any errors.

I think the "Unknown Source" indicates that the error was generated in the core C library and not in the Java layer. It seems like the DomainParticipant.enable() is returning RETCODE_ERROR. The question is why...

When you said:

I should also add that the problem occurs as I add more "participants" (i.e. more domains).

Do you mean this happens (1) when you create multiple DomainParticipant entities from within the same Java application? Or (2) do you mean different Java applications in the same machine? Or (3) do you mean something else?

If (1), is it always the same DomainParticipant that does not get enabled (e.g. when you start the 3rd participant)?

You are right in that it could be a resouce problem... In order to troubleshoot it would be helpful to have additional information.  Did you try adding the line of code I suggested in the previous posting to configure Logging with high verbosity prior to enabling the DomainParticipant?  If so, can you copy and paste the relavant output here?

Gerardo

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

We are using both multiple DomainParticipant entities from within the same Java application and different Java applications in the same machine.

 

With verbose logging, I am actually seeing 2 errors, and both seem to be resource related.  On the hunch that it is resource related, I tried changing max_object_per_thread from 1024 to 2048, but I received RETCODE_IMMUTABLE when I tried that.  I do not know what to do about that.  Here is the stac trace for the other 2 errors:

 

DDS_StringSeq_ensure_length:memory allocation: originaException in thread "main" com.rti.dds.infrastructure.RETCODE_ERROR: error creating entity

 

        at com.rti.dds.util.Utilities.rethrow(Unknown Source)

 

        at com.rti.dds.infrastructure.NativeFactoryMixin.create_entityI(Unknown Source)

 

        at com.rti.dds.domain.DomainParticipantFactoryImpl.create_participant(Unknown Source)

 

        at com.ng.etesim.dds.wrapper.DDS$RTIClasses.<init>(DDS.java:601)

 

        at com.ng.etesim.dds.wrapper.DDS$RTIClasses.<init>(DDS.java:538)

 

        at com.ng.etesim.dds.wrapper.DDS.init(DDS.java:105)

 

        at com.ng.etesim.dds.monitor.DDSMonitor.init(DDSMonitor.java:187)

 

        at com.ng.etesim.dds.logger.DDSLogger.<init>(DDSLogger.java:118)

 

        at com.ng.etesim.dds.logger.DDSLogger.<init>(DDSLogger.java:82)

 

        at com.ng.etesim.framework.api.SimulationController.startDDSLoggers(SimulationController.java:126)

 

        at com.ng.etesim.simcontrol.TTxSimController.config(TTxSimController.java:146)

 

        at com.ng.etesim.simcontrol.TTxSimController.main(TTxSimController.java:111)

 

 

 

com.rti.dds.infrastructure.RETCODE_ERROR: error creating entity

 

        at com.rti.dds.util.Utilities.rethrow(Unknown Source)

 

        at com.rti.dds.infrastructure.NativeFactoryMixin.create_entityI(Unknown Source)

 

        at com.rti.dds.domain.DomainParticipantFactoryImpl.create_participant(Unknown Source)

 

        at com.ng.etesim.dds.wrapper.DDS$RTIClasses.<init>(DDS.java:601)

 

        at com.ng.etesim.dds.wrapper.DDS$RTIClasses.<init>(DDS.java:538)

 

        at com.ng.etesim.dds.wrapper.DDS.init(DDS.java:105)

 

        at com.ng.etesim.dds.router.Port.<init>(Port.java:68)

 

        at com.ng.etesim.dds.router.DDSRouter.addPort(DDSRouter.java:67)

 

        at com.ng.etesim.sim.commmodel.CommModel.initModelConfig(CommModel.java:167)

 

        at com.ng.etesim.sim.commmodel.CommModel.register(CommModel.java:86)

 

        at com.ng.etesim.sim.commmodel.CommModel.main(CommModel.java:257)

Gerardo Pardo's picture
Offline
Last seen: 1 week 2 days ago
Joined: 06/02/2010
Posts: 602

Hello Herb,

It does appear resource related. But it is not so easy to figure our which resource without additional information. 

One thing that confuses me is that I am not seeing any of the outoput I would expect it should be coming out of the logger. I am only seeing the exceptions but with the high versobity we should be seeing a lot of other things. Maybe your application or Java VM is redirectiong the output somewhere else as this is why we are not seeing it... If that is the case a way around that would be to configure logging to output to a file. You an do this by adding the line:

        try {
        	Logger.get_instance().set_output_file( new java.io.File("MyLogOutput.txt"));
        } 	catch (Exception e) {
        	System.err.println("File exception: " + e);
        }

After this the "MyLogOutput.txt" should contain the logging output I was hoping to see... Gerardo

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Gerardo,

The file is 5 megabytes.  That is too big for here.  Let me know what to do.

 

We can drop this for a while.  I will be on vacation for a couple of weeks, and I will get back to you.

Thanks,

Herb

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Gerardo,

I have supplied the log file you needed at a safe location.  I hope you were able to access it.  Please let me know if you received the file.

Thanks,

Herb

 

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Apparently the safe location method did not work, and with your suggestion, I used the unix zip utility which resulted in a MUCH smaller file.  I will add the file in this post.  It was compressed with the following command on RedHat Linux:

  zip MyLogOutput.zip MyLogOutput.txt
  

Thanks.

File Attachments: 
Gerardo Pardo's picture
Offline
Last seen: 1 week 2 days ago
Joined: 06/02/2010
Posts: 602

Hello,

Thank for for including the ZIP file. I took a look at it and I could only find twio kinds of errors:

Several ones that start with  [D0014|ENABLE]NDDS_Transport_UDPv4_create_recvresource_rrEA:!create socket for example in line 6074, 6087, etc.

And the one that starts with  [D0014|ENABLE]REDADatabase_createCursorPerWorker:!create worker-specific object as found in line 6258

The !create socket is not fatal. This happens because you must have started multiple participants in that domain and it is not finding a free port. So it keeps iterating trying teh different ports that correspond to domain 14 in sequence (that is ports 10910, 10912, 10914, and so on) until it finds a free one at 10936 and it continues.

The second one, the !create worker-specific object is the one that causes the domain creation to fail. You were right to suspect the max_object_per_thread. Looking at the source this would be the resource limot that is causing the  !create worker-specific object to fail.

The reason you were getting a RETCODE_IMMUTABLE on the set_qos is that you must change this on the DomainParticipantFactory prior to creating any DomainParticipant on that process (i.e. from that instance of TheDomainParticipantFactory) . Once you have created a DomainParticipant from the facture the max_object_per_thread is "fixed" and can no longer be changed.

From your posting I think you already know how to change it, but I will add it here for completeness:

// This must be done before creating any DomainParticipant from the factory 
// otherwise you will get a RETCODE_IMMUTABLE because max_objects_per_thread is immutable
DomainParticipantFactoryQos factoryQos = new DomainParticipantFactoryQos();
DomainParticipantFactory.TheParticipantFactory.get_qos( factoryQos );
factoryQos.resource_limits.max_objects_per_thread = 2048;
DomainParticipantFactory.TheParticipantFactory.set_qos( factoryQos );
  
// After this the DomainParticipant (s) can be created

Let us know if this works!

Gerardo

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

I have tried that code before, and it did not work (compiles and runs but does not fix the problem).  I have tried it again, and the !create worker-specific object error is still there.

The new log file is attached.  It was created thusly:

  zip MyLogOutput2.zip MyLogOutput.txt

Thanks.

File Attachments: 
Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

I think it is the max_objects_per_thread that is immutable.  I changed it and then re-fetched the factoryQos to see if it changed, and it was still set to 1024 instead of 2048.  Something is keeping me from changing max_objects_per_thread.  Could this be some kind of license or configuration issue?

Thanks.

 

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Gerardo,

This is new code, and I looked around a found some code in another place that looks like this:

DomainParticipantFactory.get_instance().load_profiles();

domainParticipant = DomainParticipantFactory.get_instance().create_instance_with_profile(...);

domainParticipant.set_default_topic_qos_with_profile(...);

Is there a way I can change the max_objects_per_thread in this section of code?

 

Thanks.

Gerardo Pardo's picture
Offline
Last seen: 1 week 2 days ago
Joined: 06/02/2010
Posts: 602

Hello,

Yes, you can add the code I pasted in my previous posting right before, or right after the DomainParticipantFactory.get_instance().load_profiles();

It should work as long as it is called before you create the first DomainParticipant which is done in the line

domainParticipant = DomainParticipantFactory.get_instance().create_participant_with_profile(...);

If the call to DomainParticipantFactory.TheParticipantFactory.set_qos( factoryQos )  fails then it should throw the com.rti.dds.infrastructure.RETCODE_IMMUTABLE_POLICY exception right there, so you should be able to see if that works immediately. And you can also re-fetch the DomainParticipantFactory and check it as you mentioned.

The max_objects_per_thread is can be changed as long as it is done before the first DomainParticipant is created. I just tested that with a simple snipped of Java code just in case...  So perhaps there are other places where you are creating DomainParticipants that you did not notice?  Is there a way to set a breakpoint or use the log messages to make sure you are changing the DomainParticipantFactoryQos before you create the first Participant?

Gerardo 

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Gerardo,

I have a unit test that tests this method directly as the very 1st test.  We are using JUnit.  The constructor not shown just initializes some class variables.  Here is the pertinent part of the JUnit code:

    @BeforeClass
    public static void setUpClass()
    {
        Participant participant =
                new Participant_RT( "Unit_Testing_TopicWrapperTest", 42 );
        participant.setupDds( true );
    }

Here is the setupDds method code:

    void setupDds( final boolean debugDDS )
    {
        // only turn this on to try to debug a problem with the DDS core
        if ( debugDDS )
        {
            com.rti.ndds.config.Logger.get_instance().set_verbosity( LogVerbosity.NDDS_CONFIG_LOG_VERBOSITY_STATUS_ALL );
        }
        DomainParticipantFactory.get_instance().load_profiles();
        
        DomainParticipantFactoryQos factoryQos = new DomainParticipantFactoryQos();
        DomainParticipantFactory.TheParticipantFactory.get_qos( factoryQos );
        factoryQos.resource_limits.max_objects_per_thread=2048;
        DomainParticipantFactory.TheParticipantFactory.set_qos( factoryQos );
...
    }

 

Here is what happems with the set_qos call:

DDS_DomainParticipantFactoryQos_check_immutableI:ERROR: Trying to change immutable policy resource_limits.max_objects_per_thread

This is about as basic as I can get it.  Why can't I change the max_objects_per_thread value?  Is there something in the load _profiles() that can cause a problem?  Are there environment variables at play here?

Thanks,

Herb

 

Offline
Last seen: 8 years 7 months ago
Joined: 12/14/2015
Posts: 23

Gerardo,

I finally wrote a simple routine in this environment that increased max_objects_per_thread to 2048 and it worked, so I am pretty sure the RTI-DDS environment is working correctly.

I put the code you suggested at the very beginning of the program, and I removed it from everywhere else.  I started getting all of my log files - one for every channel, and I no longer received the IMMUTABLE error.  It appears this code can only be executed once successfully, so it could not be in a loop or where multiple participants were created.

I think it is working now.  Thank you.

 

Herb

 

 

Gerardo Pardo's picture
Offline
Last seen: 1 week 2 days ago
Joined: 06/02/2010
Posts: 602

Hello Herb,

Glad to hear you finally got that working! Yes, as we were discussing the max_objects_per_thread is and immutable property of the DomainParticipantFactory and for this reason it can only be modified prior to creating any DomainParticipants in that process.

Regards,

Gerardo

Offline
Last seen: 5 years 1 month ago
Joined: 08/13/2014
Posts: 55

Dear Gerardo,

I was also encountered with the following error:

DDS_DomainParticipantFactoryQos_check_immutableI:ERROR: Trying to change immutable policy resource_limits.max_objects_per_thread

But your previous comments regarding modifying immutable property of the DomainParticipantFactory prior to creating any DomainParticipants did not work for me. After inspecting my code, I realized that two entities (Waitset and GuardCondition) implicitly create a domainparticipant in my program. So I decide to get a pointer to them instead of an object in my class definition. Now my program works fine (at least the previous error has gone!). But now according to the following link, https://community.rti.com/best-practices/modern-c-api-don%E2%80%99t-declare-entities-pointers, I don't know whether it's a good work to do that or not. Please help me.
 
Bonjefir
Offline
Last seen: 2 months 3 weeks ago
Joined: 04/02/2013
Posts: 196

In general you should be able to initialize reference types with dds::core::null, like the article explains. However there seems to be a bug and that constructor is not compiling for Waitset and Condition. For that reason, in this particular case it is a valid workaround to declare your variable as a pointer.

Offline
Last seen: 5 years 1 month ago
Joined: 08/13/2014
Posts: 55

Hi Alex,

Thanks for your answer. But I was wondering why waitset and guardcondition implicitly creat a domain participant and prevent me to change the factoryqos. Can you explain that? Also, as you know, waitset and guardcondition don't provide the operations close(). So by defining them as pointer in my class definition, I think I would have some dangled pointers somewhere in my program. How should I handle the destruction of these entities? 

Best Regards,

Bonjefir