Replication error - parsing objectdb config

#1

I'm trying to replicate a database using the following config:

<server>
  <connection port="6136" max="100" />
  <data path="$objectdb/db-files" />
  <replication url="objectdb://localhost:6126/DEV1/NewMessagePipe.odb;user=admin;password=admin" />
</server>

The 6126 server is running fine but the 6136 server refuses to start - no error or other messages are output to the logfile. When I started a client pointed at the 6136 server (expecting it to fail with a connection error) it failed with the exception below.

Is there something wrong with my config?

Caused by: com.objectdb.o.UserException: Failed to validate xml file T:\felix_grid_services\ext\objectdb\2-2-1\objectdb.conf line 38: cvc-complex-type.4: Attribute 'username' must appear on element 'replication'.
at com.objectdb.o.MSG.d(MSG.java:74)
at com.objectdb.o.XMD.n(XMD.java:229)
at com.objectdb.o.XMD.j(XMD.java:144)
at com.objectdb.o.CFG.q(CFG.java:220)
at com.objectdb.o.CFG.<init>(CFG.java:203)
at com.objectdb.o.CFG.p(CFG.java:186)
at com.objectdb.o.CFG.o(CFG.java:119)
at com.objectdb.o.RCL.<clinit>(RCL.java:33)
... 96 more
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.4: Attribute 'username' must appear on element 'replication'.
at com.sun.org.apache.xerces.internal.jaxp.validation.Util.toSAXParseException(Util.java:109)
at com.sun.org.apache.xerces.internal.jaxp.validation.ErrorHandlerAdaptor.error(ErrorHandlerAdaptor.java:104)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:382)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:316)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:429)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3185)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.addDefaultAttributes(XMLSchemaValidator.java:2910)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:2098)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:705)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:335)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:533)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:220)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:322)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(XMLDocumentFragmentScannerImpl.java:1693)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:368)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:834)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:148)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1242)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.process(ValidatorImpl.java:192)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorImpl.validate(ValidatorImpl.java:159)
at javax.xml.validation.Validator.validate(Validator.java:82)
at com.objectdb.o.XMD.n(XMD.java:204)
... 102 more

 

#2

This is a bug. The username attribute was removed in the last version but the old XML schema validation was integrated into build by mistake.

Please try the fix (2.2.1_02).

Because replication is a new ObjectDB feature - please do not hesitate reporting any strange behavior that you see.

 

ObjectDB Support
#3

I can now start a replicated database and the relevant files get created under db-files\$replication but I'm having some trouble connecting to the slave database:

[ObjectDB 2.2.1_01] javax.persistence.PersistenceException
Replicated database objectdb:///localhost:6136/TestReplication.odb;user=admin;password=admin is unavaliable (error 538)
at com.objectdb.jpa.EMF.createEntityManager(EMF.java:161)
at rbccm.felix.objectdb.test.TestObjectDB.testReplication(TestObjectDB.java:287)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:592)
at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99)
at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75)
at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45)
at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66)
at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35)
at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42)
at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34)
at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: com.objectdb.o.UserException: Replicated database objectdb:///localhost:6136/TestReplication.odb;user=admin;password=admin is unavaliable
at com.objectdb.o.MSG.d(MSG.java:74)
at com.objectdb.o.SMR.V(SMR.java:600)
at com.objectdb.o.SHN.W(SHN.java:237)
at com.objectdb.o.SHN.J(SHN.java:113)
at com.objectdb.o.HND.run(HND.java:133)
at java.lang.Thread.run(Thread.java:619)

My master server is running on port 6136 while the slave runs on 6138. Config from the slave looks as follows:

 <server>
  <connection port="6138" max="100" />
  <data path="$objectdb/db-files" />
  <replication url="objectdb://localhost:6136/TestReplication.odb;user=admin;password=admin" />
</server>

My test saves Point and Line objects (as per the tutorial) to the master database and then attempts to count the number of Points using a connection to the slave database. Should this work? I've tried the slave query with the master running and with it offline but have hit the same result.

The test code is as follows:

  EntityManagerFactory masterEmf = Persistence.createEntityManagerFactory("objectdb://localhost:6136/TestReplication.odb;user=admin;password=admin");
  EntityManagerFactory replicatedEmf = Persistence.createEntityManagerFactory("objectdb://localhost:6138///localhost:6136/TestReplication.odb;user=admin;password=admin");
  try {
   EntityManager masterManager = masterEmf.createEntityManager();
   masterManager.getTransaction().begin();
         for (int i = 0; i < 1000; i++) {
             Point p = new Point(i, i);
             Line l = new Line(p, p);
             masterManager.persist(p);
             masterManager.persist(l);
         }
         masterManager.getTransaction().commit();
         masterManager.close();
        
         EntityManager replicatedManager = replicatedEmf.createEntityManager();
         Query replicatedQuery = replicatedManager.createQuery("SELECT COUNT(p) FROM Point p");
         System.out.println("Total Points: " + replicatedQuery.getSingleResult());
         replicatedManager.close();
        
  } catch (Throwable e) {
   e.printStackTrace();
  } finally {
   masterEmf.close();
   replicatedEmf.close();
  }

 

#4

Your configuration seems fine.

Please verify that recording is enabled for the master server (it is disabled by default since version 2.2.0).

Then check the log files of both servers (and mainly the master).

 

ObjectDB Support
#5

Recording is enabled:

<recording enabled="true" sync="false" path="." mode="write" />

Logs from the master and slave are attached but neither show any error.

#6

The log files indicate that the replication works, but I notice now that the slave url is invalid. It should be:

objectdb://localhost:6138//localhost:6136...

and not

objectdb://localhost:6138///localhost:6136...

It seems that the cause is a documentation error (that I just fixed), sorry.

ObjectDB Support
#7

Good spot - its working now.

Thanks!

Reply