Exception when unmarshalling XML with XStream - java

I have created some Converter for a javafx.scene.shape.Path which is basically a Bèzier-path. To do that I convert the path elements that are of type MoveTo and CubicCurveTo, for which I have also converters:
public class MoveToConverter implements Converter {
#Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
writer.startNode("move-to");
MoveTo start = (MoveTo) source;
writer.addAttribute("startX", String.valueOf(start.getX()));
writer.addAttribute("startY", String.valueOf(start.getY()));
writer.endNode();
}
#Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
reader.moveDown();
MoveTo moveTo = new MoveTo();
moveTo.setX(Double.valueOf(reader.getAttribute("startX")));
moveTo.setY(Double.valueOf(reader.getAttribute("startY")));
reader.moveUp();
return moveTo;
}
#Override
public boolean canConvert(Class type) {
return MoveTo.class.equals(type);
}
}
public class CubicCurveToConverter implements Converter {
#Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
CubicCurveTo curveTo = (CubicCurveTo) source;
writer.startNode("cubic-curve-to");
writer.addAttribute("controlX1", String.valueOf(curveTo.getControlX1()));
writer.addAttribute("controlY1", String.valueOf(curveTo.getControlY1()));
writer.addAttribute("controlX2", String.valueOf(curveTo.getControlX2()));
writer.addAttribute("controlY2", String.valueOf(curveTo.getControlY2()));
writer.addAttribute("x", String.valueOf(curveTo.getX()));
writer.addAttribute("y", String.valueOf(curveTo.getY()));
writer.endNode();
}
#Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
reader.moveDown();
CubicCurveTo curveTo = new CubicCurveTo();
curveTo.setX(Double.valueOf(reader.getAttribute("x")));
curveTo.setY(Double.valueOf(reader.getAttribute("y")));
curveTo.setControlX1(Double.valueOf(reader.getAttribute("controlX1")));
curveTo.setControlY1(Double.valueOf(reader.getAttribute("controlY1")));
curveTo.setControlX2(Double.valueOf(reader.getAttribute("controlX2")));
curveTo.setControlY2(Double.valueOf(reader.getAttribute("controlY2")));
reader.moveUp();
return curveTo;
}
#Override
public boolean canConvert(Class type) {
return CubicCurveTo.class.equals(type);
}
}
public class PathConverter implements Converter {
#Override
public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) {
Path path = (Path) o;
List<PathElement> elements = path.getElements();
writer.startNode("bezier-path");
writer.addAttribute("count", String.valueOf(elements.size()));
MoveTo start = (MoveTo) elements.get(0);
marshallingContext.convertAnother(start);
// serialize start
for (int i = 1; i < elements.size(); i++) {
CubicCurveTo curveTo = (CubicCurveTo) elements.get(i);
marshallingContext.convertAnother(curveTo);
}
writer.endNode();
}
#Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
reader.moveDown();
Path path = new Path();
path.setStrokeWidth(2);
path.setStroke(Color.RED);
int nbElements = Integer.parseInt(reader.getAttribute("count"));
MoveTo moveTo = (MoveTo) context.convertAnother(path, MoveTo.class);
path.getElements().add(moveTo);
for (int i = 1; i < nbElements; i++) {
CubicCurveTo curveTo = (CubicCurveTo) context.convertAnother(path, CubicCurveTo.class);
path.getElements().add(curveTo);
System.out.println("Added curve to: "+curveTo);
}
reader.moveUp();
return path;
}
#Override
public boolean canConvert(Class aClass) {
return Path.class.equals(aClass);
}
}
And I have this test code:
Path path = new Path();
path.getElements().add(new MoveTo(2, 1));
path.getElements().add(new CubicCurveTo(1, 2, 3, 4, 5, 6));
path.getElements().add(new CubicCurveTo(11, 12, 13, 14, 15, 16));
path.getElements().add(new CubicCurveTo(21, 22, 23, 24, 25, 26));
path.getElements().add(new CubicCurveTo(31, 32, 33, 34, 35, 36));
path.getElements().add(new CubicCurveTo(41, 42, 43, 44, 45, 46));
XStream xStream = new XStream();
xStream.registerConverter(converter);
xStream.registerConverter(new MoveToConverter());
xStream.registerConverter(new CubicCurveToConverter());
File f = File.createTempFile(getClass().getName(), ".xml");
OutputStream os = new FileOutputStream(f);
xStream.toXML(path, os);
Object result = xStream.fromXML(f);
assertEquals(path.toString(), result.toString());
f.delete();
The file that is created when mashalling the path looks like this, which is what I basically want:
<javafx.scene.shape.Path>
<bezier-path count="6">
<move-to startX="2.0" startY="1.0"/>
<cubic-curve-to controlX1="1.0" controlY1="2.0" controlX2="3.0" controlY2="4.0" x="5.0" y="6.0"/>
<cubic-curve-to controlX1="11.0" controlY1="12.0" controlX2="13.0" controlY2="14.0" x="15.0" y="16.0"/>
<cubic-curve-to controlX1="21.0" controlY1="22.0" controlX2="23.0" controlY2="24.0" x="25.0" y="26.0"/>
<cubic-curve-to controlX1="31.0" controlY1="32.0" controlX2="33.0" controlY2="34.0" x="35.0" y="36.0"/>
<cubic-curve-to controlX1="41.0" controlY1="42.0" controlX2="43.0" controlY2="44.0" x="45.0" y="46.0"/>
</bezier-path>
</javafx.scene.shape.Path>
However when unmarshalling the XML I run into this exception:
com.thoughtworks.xstream.converters.ConversionException: only START_TAG can have attributes END_TAG seen ...<bezier-path count="6">\n <move-to startX="2.0" startY="1.0"/>... #3:41 : only START_TAG can have attributes END_TAG seen ...<bezier-path count="6">\n <move-to startX="2.0" startY="1.0"/>... #3:41
---- Debugging information ----
message : only START_TAG can have attributes END_TAG seen ...<bezier-path count="6">\n <move-to startX="2.0" startY="1.0"/>... #3:41
cause-exception : java.lang.IndexOutOfBoundsException
cause-message : only START_TAG can have attributes END_TAG seen ...<bezier-path count="6">\n <move-to startX="2.0" startY="1.0"/>... #3:41
class : javafx.scene.shape.Path
required-type : javafx.scene.shape.Path
converter-type : ch.sahits.game.openpatrician.persistence.converter.PathConverter
path : /javafx.scene.shape.Path/bezier-path
line number : 3
version : 1.4.8
-------------------------------
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1154)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1096)
at ch.sahits.game.openpatrician.persistence.converter.PathConverterTest.shouldConvertObjectToXMLAndBack(PathConverterTest.java:49)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.IndexOutOfBoundsException: only START_TAG can have attributes END_TAG seen ...<bezier-path count="6">\n <move-to startX="2.0" startY="1.0"/>... #3:41
at org.xmlpull.mxp1.MXParser.getAttributeValue(MXParser.java:927)
at com.thoughtworks.xstream.io.xml.XppReader.getAttribute(XppReader.java:139)
at com.thoughtworks.xstream.io.ReaderWrapper.getAttribute(ReaderWrapper.java:52)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:53)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at ch.sahits.game.openpatrician.persistence.converter.PathConverter.unmarshal(PathConverter.java:52)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
... 36 more
The line 52 in PathConverter points to the this line (first call in the for-loop):
CubicCurveTo curveTo = (CubicCurveTo) context.convertAnother(path, CubicCurveTo.class);
My guess is that the problem has something to do with the moveDown and moveUp method on the unmarshal method, so that the reader is still in the state where it expects the end node of move-to. For the other two converters I also have tests, which run fine, so the problem seems to lie in the combination and the call to context.convertAnother.
I would like to know where my thinking in creating the converter went wrong and how this can be solved.

You're operating on a stream. If the next step does not read the tag's value. May cause an error
try:
reader.moveDown();
Path path = new Path();
path.setStrokeWidth(2);
path.setStroke(Color.RED);
int nbElements = Integer.parseInt(reader.getAttribute("count"));
MoveTo moveTo = (MoveTo) context.convertAnother(path, MoveTo.class);
path.getElements().add(moveTo);
reader.moveUp();
for (int i = 1; i < nbElements; i++) {
reader.moveDown();
CubicCurveTo curveTo = (CubicCurveTo) context.convertAnother(path, CubicCurveTo.class);
path.getElements().add(curveTo);
System.out.println("Added curve to: "+curveTo);
reader.moveUp();
}
return path;

Related

IOException while executing junit on file base services

I have below 2 Junits.
public class TransactionManagerTest {
String fileName = "data/test/tnx-log/tnc.log";
#Test
public void beginTransactionTest_withEmptyTxnLogFile() throws IOException, ParseException {
new File(fileName).delete();
TransactionManager transactionManager = new TransactionManagerImpl(fileName);
transactionManager.beginTransaction();
ZonedDateTime transactionStartDate = transactionManager.getTransactionStartDate();
ZonedDateTime transactionEndDate = transactionManager.getTransactionEndDate();
ZonedDateTime now = ZonedDateTime.now();
Assert.assertEquals(now.getDayOfMonth(), transactionStartDate.getDayOfMonth());
Assert.assertEquals(now.getMonth(), transactionStartDate.getMonth());
Assert.assertEquals(now.getYear(), transactionStartDate.getYear());
Assert.assertEquals(0, transactionStartDate.getHour());
Assert.assertEquals(0, transactionStartDate.getMinute());
Assert.assertEquals(0, transactionStartDate.getSecond());
Assert.assertEquals(now.getDayOfMonth(), transactionEndDate.getDayOfMonth());
Assert.assertEquals(now.getMonth(), transactionEndDate.getMonth());
Assert.assertEquals(now.getYear(), transactionEndDate.getYear());
Assert.assertEquals(now.getHour(), transactionEndDate.getHour());
}
#Test
public void beginTransactionTest_success() throws IOException, ParseException {
File file = new File(fileName);
System.out.println(file.exists());
System.out.println(file.delete());
TransactionManager transactionManager = new TransactionManagerImpl(fileName);
File localFile = new File(fileName);
boolean txnLogFileExist = localFile.exists();
localFile = null;
Assert.assertTrue(txnLogFileExist);
ZonedDateTime startDate = ZonedDateTime.of(2019, 04, 25, 10, 35, 30, 000, ZoneId.of("UTC"));
ZonedDateTime endDate = ZonedDateTime.of(2019, 04, 25, 10, 40, 30, 000, ZoneId.of("UTC"));
transactionManager.beginTransaction(startDate, endDate);
transactionManager.markSuccess();
ZonedDateTime transactionStartDate = transactionManager.getTransactionStartDate();
ZonedDateTime transacitonEndDate = transactionManager.getTransactionEndDate();
Assert.assertTrue(endDate.isEqual(transactionStartDate));
Assert.assertNotNull(transacitonEndDate);
}
And below is the implementation of My TransacitonManager and CsvService.
public class TransactionManagerImpl implements TransactionManager {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private CsvService csvService;
public TransactionManagerImpl(String txnLogFile) throws IOException {
this.csvService = new CsvServiceImpl(txnLogFile);
}
public class CsvServiceImpl implements CsvService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private String txnLogFile;
public CsvServiceImpl(String txnLogFile) throws IOException {
this.txnLogFile = txnLogFile;
createTxnInfoFile();
}
#Override
public void createTxnInfoFile() throws IOException {
File file = new File(txnLogFile);
if (!file.exists()) {
boolean directoryStructureCreated = file.getParentFile().mkdirs();
logger.info("Directory structure created {} {} ", txnLogFile, directoryStructureCreated);
boolean fileCreated = file.createNewFile();
logger.info("txn log file created {} {} ", txnLogFile, fileCreated);
}
file = null;
}
The issue is that my first JUnit runs fine, but when i execute the 2nd junit the CsvService.createTxnInfoFile gets IOException
java.io.IOException: Access is denied
at java.io.WinNTFileSystem.createFileExclusively(Native Method)
at java.io.File.createNewFile(File.java:1012)
at dummy.name.service.impl.CsvServiceImpl.createTxnInfoFile(CsvServiceImpl.java:88)
at dummy.name.service.impl.CsvServiceImpl.<init>(CsvServiceImpl.java:29)
at dummy.name.service.impl.TransactionManagerImpl.<init>(TransactionManagerImpl.java:25)
at dummy.name.service.TransactionManagerTest.beginTransactionTest_success(TransactionManagerTest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:39)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:79)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:70)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
output
2019-04-22 08:40:28,895 [main] INFO g.t.service.impl.CsvServiceImpl - Directory structure created data/test/tnx-log/tnc.log false
2019-04-22 08:40:28,895 [main] INFO g.t.service.impl.CsvServiceImpl - file.getAbsoluteFile() : C:\Users\jigar\apps\workspace\trade-publisher\data\test\tnx-log\tnc.log canWrite() : false
2019-04-22 08:40:28,895 [main] INFO g.t.service.impl.CsvServiceImpl - txn log file created data/test/tnx-log/tnc.log true
2019-04-22 08:40:28,957 [main] INFO g.t.service.impl.CsvServiceImpl - Directory structure created data/test/tnx-log/tnc.log false
2019-04-22 08:40:28,957 [main] INFO g.t.service.impl.CsvServiceImpl - file.getAbsoluteFile() : C:\Users\jigar\apps\workspace\trade-publisher\data\test\tnx-log\tnc.log canWrite() : false
#Override
public void createTxnInfoFile() throws IOException {
File file = new File(txnLogFile);
if (!file.exists()) {
boolean directoryStructureCreated = file.getParentFile().mkdirs();
logger.info("Directory structure created {} {} ", txnLogFile, directoryStructureCreated);
logger.info("file.getAbsoluteFile() : " + file.getAbsoluteFile() + " canWrite() : " + file.canWrite());
boolean fileCreated = file.createNewFile();
logger.info("txn log file created {} {} ", txnLogFile, fileCreated);
}
file = null;
}
Issue resolved, instead of deleting and creating new file for every test. I am now deleting the content of file without deleting the actual file as below.
#After
public void tearDown() throws FileNotFoundException {
this.transactionManager = null;
PrintWriter writer = new PrintWriter(fileName);
writer.print("");
writer.close();
}

Mockito (Junit) unable to iterate through JSONArray object

I am trying to write a unit test for class DataHandler.java this is in turn calling a parseDebeziumSchema method from SchemaParsor class.
This method converts a string to JSONArray, but when I am trying to mock it using when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray); it is throwing java.lang.NoSuchMethodError: org.json.JSONArray.iterator()Ljava/util/Iterator exception.
The full stack trace is as follows, also I am attaching the DataHandler class, DataHandlerTest class and parseDebeziumSchema method codes as well:
java.lang.NoSuchMethodError: org.json.JSONArray.iterator()Ljava/util/Iterator;
at com.xoom.transformer.dbschemahandler.SchemaParsor.parseDebeziumSchema(SchemaParsor.java:43)
at com.xoom.transformer.utils.DataHandlerTest.testdataProcessor(DataHandlerTest.java:52)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
DataHandlerTest.java:
public class DataHandlerTest {
#Mock
private SchemaManager schemaManager;
#InjectMocks
private SchemaParsor schemaParsor;
#InjectMocks
private DataHandler dataHandler;
//Variables
private final String json = "{\"schema\":{\"type\":\"struct\",\"fields\":[{\"type\":\"struct\",\"fields\":[{\"type\":\"string\",\"optional\":false,\"field\":\"recipe_name\"}],\"optional\":true,\"name\":\"_0.0.0.160.Debezium_test.recipes.Value\",\"field\":\"before\"},{\"type\":\"struct\",\"fields\":[{\"type\":\"string\",\"optional\":false,\"field\":\"recipe_name\"}],\"optional\":true,\"name\":\"_0.0.0.160.Debezium_test.recipes.Value\",\"field\":\"after\"},{\"type\":\"struct\",\"fields\":[{\"type\":\"string\",\"optional\":true,\"field\":\"version\"},{\"type\":\"string\",\"optional\":false,\"field\":\"name\"},{\"type\":\"int64\",\"optional\":false,\"field\":\"server_id\"},{\"type\":\"int64\",\"optional\":false,\"field\":\"ts_sec\"},{\"type\":\"string\",\"optional\":true,\"field\":\"gtid\"},{\"type\":\"string\",\"optional\":false,\"field\":\"file\"},{\"type\":\"int64\",\"optional\":false,\"field\":\"pos\"},{\"type\":\"int32\",\"optional\":false,\"field\":\"row\"},{\"type\":\"boolean\",\"optional\":true,\"default\":false,\"field\":\"snapshot\"},{\"type\":\"int64\",\"optional\":true,\"field\":\"thread\"},{\"type\":\"string\",\"optional\":true,\"field\":\"db\"},{\"type\":\"string\",\"optional\":true,\"field\":\"table\"},{\"type\":\"string\",\"optional\":true,\"field\":\"query\"}],\"optional\":false,\"name\":\"io.debezium.connector.mysql.Source\",\"field\":\"source\"},{\"type\":\"string\",\"optional\":false,\"field\":\"op\"},{\"type\":\"int64\",\"optional\":true,\"field\":\"ts_ms\"}],\"optional\":false,\"name\":\"_0.0.0.160.Debezium_test.recipes.Envelope\"},\"payload\":{\"before\":null,\"after\":{\"recipe_name\":\"Chicken\"},\"source\":{\"version\":\"0.8.2\",\"name\":\"10.0.0.160\",\"server_id\":1,\"ts_sec\":1549019230,\"gtid\":null,\"file\":\"bin.000035\",\"pos\":263,\"row\":0,\"snapshot\":false,\"thread\":28,\"db\":\"Debezium_test\",\"table\":\"recipes\",\"query\":null},\"op\":\"c\",\"ts_ms\":1549019230377}}";
private final String topic_name = "database.table";
private final int partition = 1;
//Creating JSONObject
private Iterator iterator = null;
private JSONArray jsonArray=new JSONArray();
private JSONObject jsonObject=new JSONObject();
#Test //(expected=Exception.class)
public void testdataProcessor() throws JsonParseException, JSONException {
jsonObject.put("field","recipe_name");
jsonObject.put("type","string");
jsonArray.put(jsonObject);
dataHandler.dataProcessor(json, topic_name, partition);
when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray);
verify(dataHandler, Mockito.times(1)).dataProcessor(json, topic_name, partition);
}
}
parseDebeziumSchema
public JSONArray parseDebeziumSchema(String json)throws JsonParseException{
debezium_schema_arrjson=new JSONArray();
try{
System.out.println("==========Raw Json===="+json);
JSONObject jsonObj=new JSONObject(json);
if(jsonObj.length()>0){
JSONObject schema_detail=jsonObj.getJSONObject("schema");
System.out.println("==========schema_detail===="+schema_detail);
JSONArray fields_json_arr=schema_detail.getJSONArray("fields");
System.out.println("==========fields_json_arr===="+fields_json_arr);
for(Object field_json_obj:fields_json_arr){
System.out.println("======field_json_obj===={}"+field_json_obj);
JSONObject jsonObject_field=jsonUtils.objectToJSONObject(field_json_obj);
JSONArray fields_json_arr_in=(JSONArray)jsonObject_field.get("fields");
for(Object j_obj:fields_json_arr_in){
debezium_schema_json=new JSONObject();
JSONObject jsonObject=jsonUtils.objectToJSONObject(j_obj);
debezium_schema_json.put("type",jsonObject.get("type"));
debezium_schema_json.put("field",jsonObject.get("field"));
debezium_schema_arrjson.put(debezium_schema_json);
}
break;
}
}
}
catch(Exception ex){
LOGGER.error("Cannot parse JSON for spring.application.json: "+json,ex);
throw new JsonParseException("SchemaParsor.parseDebeziumSchema. Debezium schema parse error.");
}
return debezium_schema_arrjson;
}
Any help will be highly appreciated.
There are two problems in your test:
Call stubbing must be configured before the actual interaction. So just swap these lines:
dataHandler.dataProcessor(json, topic_name, partition);
when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray); //stub parseDebeziumSchema
Mockito.verify is for verification of interaction with a mock. But in your code, you are verifying a method call on the object under test. You don't see this error because your code breaks at point 1. Remove this line:
verify(dataHandler, Mockito.times(1)).dataProcessor(json, topic_name, partition);
To summarize, your code should look like the one below. I've also added verification that schemaParsor.parseDebeziumSchema(json) is called exactly once
#Test
public void testdataProcessor() throws JsonParseException, JSONException {
jsonObject.put("field","recipe_name");
jsonObject.put("type","string");
jsonArray.put(jsonObject);
when(schemaParsor.parseDebeziumSchema(json)).thenReturn(jsonArray); //stub parseDebeziumSchema
dataHandler.dataProcessor(json, topic_name, partition);
verify(schemaParsor, times(1)).parseDebeziumSchema(json); //verify that parseDebeziumSchema is called exactly once
}

OrientDB 3.0.4 Java OValidationException: The field has been declared as EMBEDDEDLIST but an incompatible type is used

I am using OrientDB version 3.0.4
with Java and orientdb-client.3.0.4 Java driver/library.
I am trying to use EMBEDDEDLIST type as follows:
DB schema:
create class Phone EXTENDS V
create property Phone.number String
create class Profile EXTENDS V
create property Profile.name String
create property Profile.phone embeddedList Phone
Using OrientDB console, following works:
CREATE VERTEX Profile SET name = "User1", phone = [{ "number" : "914" }, { "number" : "212" }]
SELECT * From Profile where name="User1"
+----+------+-------+-----+-------------------------------------+
|# |#RID |#CLASS |name |phone |
+----+------+-------+-----+-------------------------------------+
|0 |#198:2|Profile|User1|[Phone{number:914},Phone{number:212}]|
+----+------+-------+-----+-------------------------------------+
Using Java It fails:
While trying to create the Profile Vertex having two Phone(s) objects stored as List (ArrayList), code fails with following exception:
com.orientechnologies.orient.core.exception.OValidationException: The field 'Profile.phone' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: Phone{number:212}
DB name="test"
Error Code="4"
at com.orientechnologies.orient.core.record.impl.ODocument.validateEmbedded(ODocument.java:814)
Here is the code:
public void insertProfileTest() throws JsonProcessingException {
LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("name").toString());
LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("phone").toString());
LOGGER.info(dbSession.getMetadata().getSchema().getClass(Phone.class).getProperty("number").toString());
// Init
Profile userProfile = new Profile("Jane Doe");
Phone homePhone = new Phone("212");
Phone cellPhone = new Phone("718");
userProfile.addPhone(homePhone);
userProfile.addPhone(cellPhone);
final String json = MAPPER.writeValueAsString(userProfile);
LOGGER.info("Profile JSON:" + json);
LOGGER.info("Phone Class :" + userProfile.getPhone().getClass().getName());
// DB
final OVertex profileVertex = dbSession.newVertex("Profile");
profileVertex.setProperty("name", userProfile.getName());
profileVertex.setProperty("phone", userProfile.getPhone(), OType.EMBEDDEDLIST);
// Fails to Save -
// The field 'Profile.phone' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: com.sample.profile.Phone#32f232a5
profileVertex.save();
}
Here is the output:
14:11:00.124 [main] INFO com.sample.profile.ProfileTest - Initializing begin
14:11:01.187 [main] INFO com.sample.profile.ProfileTest - OrientDB [remote:localhost/test] Status: [OPEN]
14:11:01.191 [main] INFO com.sample.profile.ProfileTest - name (type=STRING)
14:11:01.192 [main] INFO com.sample.profile.ProfileTest - phone (type=EMBEDDEDLIST)
14:11:01.192 [main] INFO com.sample.profile.ProfileTest - number (type=STRING)
14:11:01.233 [main] INFO com.sample.profile.ProfileTest - Profile JSON:{"name":"Jane Doe1","phone":[{"number":"212"},{"number":"718"}]}
14:11:01.234 [main] INFO com.sample.profile.ProfileTest - Phone Class :java.util.ArrayList
Jul 12, 2018 2:11:01 PM com.orientechnologies.common.log.OLogManager log
INFO: Orient Engine is shutting down...
com.orientechnologies.orient.core.exception.OValidationException: The field 'Profile.phone' has been declared as EMBEDDEDLIST but an incompatible type is used. Value: Phone{number:212}
DB name="test"
Error Code="4"
at com.orientechnologies.orient.core.record.impl.ODocument.validateEmbedded(ODocument.java:814)
at com.orientechnologies.orient.core.record.impl.ODocument.validateField(ODocument.java:601)
at com.orientechnologies.orient.core.record.impl.ODocument.validate(ODocument.java:2365)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.saveInternal(ODatabaseDocumentAbstract.java:2057)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.save(ODatabaseDocumentAbstract.java:2042)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.save(ODatabaseDocumentAbstract.java:84)
at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:2109)
at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:2100)
at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:63)
at com.sample.profile.ProfileTest.insertProfileTest(ProfileTest.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Here are the Java classes:
package com.sample.profile;
public class Phone {
private String number;
public Phone() {
}
public Phone(String number) {
this.number = number;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
#Override
public String toString() {
return "Phone{" +
"number:" + number +
'}';
}
}
package com.sample.profile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class Profile {
private String name;
private Collection phone;
public Profile() {
}
public Profile(String name) {
this.name = name;
}
public Profile(String name, Collection phone) {
this.name = name;
this.phone = phone;
}
public void addPhone(Phone phoneNumber)
{
if (this.phone == null) {
this.phone = new ArrayList();
}
this.phone.add(phoneNumber);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection getPhone() {
return phone;
}
public void setPhone(Collection phone) {
this.phone = phone;
}
#Override
public String toString() {
return "Profile{" +
"name='" + name + '\'' +
", phone=" + Arrays.toString(phone.toArray()) +
'}';
}
}
Solution:
I resolved the issue as follows:
public void insertProfileTest() throws JsonProcessingException {
LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("name").toString());
LOGGER.info(dbSession.getMetadata().getSchema().getClass(Profile.class).getProperty("phone").toString());
LOGGER.info(dbSession.getMetadata().getSchema().getClass(Phone.class).getProperty("number").toString());
// Init
Profile userProfile = new Profile("Jane Doe");
Phone homePhone = new Phone("212");
Phone cellPhone = new Phone("718");
userProfile.addPhone(homePhone);
userProfile.addPhone(cellPhone);
final String json = MAPPER.writeValueAsString(userProfile);
LOGGER.info("Profile JSON:" + json);
LOGGER.info("Phone Class :" + userProfile.getPhone().getClass().getName());
// DB
List phoneVertexList = new ArrayList();
for (Phone phone: userProfile.getPhone()) {
final OVertex phoneVertex = dbSession.newVertex("Phone");
phoneVertex.setProperty("number", phone.getNumber());
phoneVertexList.add(phoneVertex);
}
final OVertex profileVertex = dbSession.newVertex("Profile");
profileVertex.setProperty("name", userProfile.getName());
profileVertex.setProperty("phone", phoneVertexList, OType.EMBEDDEDLIST);
profileVertex.save();
}
What is not clear to me as per the documentation at
https://orientdb.com/docs/last/general/Types.html for the EMBEDDEDLIST
that it should be of Java type List<Object> but I had to use List<OVertex> .
The documentation states "The Records are contained inside the owner. The contained records have no Record ID's and are reachable only by navigating the owner record" but then in this case Phone vertexes were created as follows:
select * from Profile
+----+-----+-------+--------+-------------------------------------+
|# |#RID |#CLASS |name |phone |
+----+-----+-------+--------+-------------------------------------+
|0 |#41:0|Profile|Jane Doe|[Phone{number:212},Phone{number:718}]|
+----+-----+-------+--------+-------------------------------------+
select * from Phone
+----+-----+------+------+
|# |#RID |#CLASS|number|
+----+-----+------+------+
|0 |#33:0|Phone |212 |
|1 |#34:0|Phone |718 |
+----+-----+------+------+
The documentation at following locations seems very minimal and do not provide example of EMBEDDEDLIST.
https://orientdb.com/docs/last/java/Java-Query-API.html
https://tinkerpop.apache.org/docs/current/reference/#connecting-via-java
I am wondering if anyone can point to better documentation for use of Java API to interact with OrientDB or any GraphDB.

Eclipse Plugin: If Annotation is not present, AbstractAnnotationHover results in a NullPointerException

What i have: I develop an Eclipse editor and override the getTextHover Method in the SourceViewerConfiguration with this method:
public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
return new AbstractAnnotationHover(true) {
public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
IAnnotationModel model = ((SourceViewer) textViewer).getAnnotationModel();
#SuppressWarnings("unchecked")
Iterator<Annotation> parent =
((IAnnotationModelExtension2)model).getAnnotationIterator(hoverRegion.getOffset(),
hoverRegion.getLength(), true, true);
Iterator<?> iter = new JavaAnnotationIterator(parent, false);
Annotation annotation = null;
Position position = null;
while (iter.hasNext()) {
Annotation a = (Annotation) iter.next();
Position p = model.getPosition(a);
annotation = a;
position = p;
}
return new AnnotationInfo(annotation, position, textViewer) {
public ICompletionProposal[] getCompletionProposals() {
ICompletionProposal proposal1 = null;
IMarkerResolution [] resolutions = null;
ICompletionProposal [] com = null;
if (annotation instanceof MarkerAnnotation) {
resolutions = new ErrorResolution().getResolutions(((MarkerAnnotation) annotation).getMarker());
if(resolutions.length != 0){
proposal1 = new MarkerResolutionProposal(resolutions[0],
((MarkerAnnotation) annotation).getMarker());
return new ICompletionProposal[] { proposal1 };
}
}
return com ;
}
};
}
};
}
It displays QuickFixes when hovering over an annotated error in the code viewer. But if i hover over an error, which has no quick fix or just a correct line of code, it results in the following error:
org.eclipse.swt.SWTException: Failed to execute runnable (java.lang.NullPointerException)
at org.eclipse.swt.SWT.error(SWT.java:4491)
at org.eclipse.swt.SWT.error(SWT.java:4406)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:138)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4155)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3772)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$4.run(PartRenderingEngine.java:1127)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:337)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1018)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:156)
at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:694)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:337)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:606)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:139)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:669)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:608)
at org.eclipse.equinox.launcher.Main.run(Main.java:1515)
at org.eclipse.equinox.launcher.Main.main(Main.java:1488)
Caused by: java.lang.NullPointerException
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover$AnnotationInformationControl.createAnnotationInformation(AbstractAnnotationHover.java:329)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover$AnnotationInformationControl.deferredCreateContent(AbstractAnnotationHover.java:282)
at org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover$AnnotationInformationControl.setInput(AbstractAnnotationHover.java:186)
at org.eclipse.jface.text.AbstractInformationControlManager.internalShowInformationControl(AbstractInformationControlManager.java:1181)
at org.eclipse.jface.text.AbstractInformationControlManager.presentInformation(AbstractInformationControlManager.java:1150)
at org.eclipse.jface.text.AbstractHoverInformationControlManager.presentInformation(AbstractHoverInformationControlManager.java:902)
at org.eclipse.jface.text.TextViewerHoverManager.doPresentInformation(TextViewerHoverManager.java:243)
at org.eclipse.jface.text.TextViewerHoverManager$5.run(TextViewerHoverManager.java:233)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
... 24 more
and the message of the annotation is not shown.
What I want: I want, that if i hover iver an error where a quick fix is available, the quick fix is shown and if there is no one, just the annotation message is shown.

Selenium/JUnit, NullPointerException with a findBy annotation

I create a Java project for training with Selenium and JUnit. A first test connect the user to the website, the second test check an information in the homepage when the user is connected. I don't understand why my second test begin and stop with a NullPointerException...
I use this files :
A main files => for declare a JunitCore and run two class test (via jCore.run(test1.class, test2.class)
main :
public class Main {
public static void main(String[] args){
JUnitCore jCore = new JUnitCore();
//jCore.addListener(new ExecutionListener());
jCore.run(WebsiteLoginTest.class, WebsiteCheckEventTest.class);
}
}
Two tests class files :
test1.java :
public class Test1 {
#Test
public void testlogin(){
WebsiteHomePage homePage = new WebsiteHomePage().open();
homePage.login(...);
}
}
test2.java :
public class WebsiteCheckEventTest {
#Test
public void websiteCheckEvent(){
System.out.println("a");
WebsiteHomePageConnected homePageConnected = new WebsiteHomePageConnected();
System.out.println("b");
homePageConnected.checkEvent();
System.out.println("c");
}
}
And two "page" files : (use page object pattern)
WebsiteHomePage (no logged) :
public class WebsiteHomePage extends WebsitePage<WebsiteHomePage> {
#FindBy(id = "usernameLogin") WebElement usernameInputText;
#FindBy(id = "passwordLogin") WebElement passwordInputText;
#FindBy(id = "loginSubmit") WebElement loginInputSubmit;
#Override
public ExpectedCondition getPageLoadCondition() {
return ExpectedConditions.titleContains("Homepage");
}
#Override
public String getPageUrl() {
return "";
}
public void login(String univers, String login, String password){
usernameInputText.sendKeys(login);
passwordInputText.sendKeys(password);
loginInputSubmit.click();
}
public WebsiteHomePage open() {
return new WebsiteHomePage().openPage(WebsiteHomePage.class);
}
}
WebsiteHomePageConnected (when the user is connected via the first test) :
public class WebsiteHomePageConnected extends WebsitePage<WebsiteHomePageConnected> {
#FindBy(id = "playerName") WebElement playerNameLi;
#FindBy(id = "eventContent") WebElement eventContentDiv;
#FindBy(id = "eventListWrap") WebElement eventListDiv;
#Override
public ExpectedCondition getPageLoadCondition() {
return ExpectedConditions.visibilityOf(playerNameLi);
}
#Override
public String getPageUrl() {
return "";
}
public void checkEvent(String event){
System.out.println("111"); // is displayed in the console
eventContentDiv.click();
System.out.println("222"); // isn't displayed in the console
}
}
When I run the program, the console shows :
a
b
c
111
...but no 222, the program stop in the WebsiteHomePageConnected file in the line with "eventContentDiv.click()" without any error message.
In the main file, if I uncomment //jCore.addListener(new ExecutionListener()) the console show :
a
b
c
111
Execution of test case failed : java.lang.NullPointerException
at page.WebsiteHomePageConnected.checkEvent(WebsiteHomePageConnected.java:34)
at test.WebsiteCheckEventTest.websiteCheckEvent(WebsiteCheckEventTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.runner.JUnitCore.run(JUnitCore.java:105)
at org.junit.runner.JUnitCore.run(JUnitCore.java:94)
at Main.main(Main.java:32)
So, the "eventContentDiv" seems be the problem, but when I check manually the website, after connection, I find the div with the id "eventContent" (via firebug ctrl+f). Manually, More precisely :
I go to the homepage website
I enter log and password, I submit
Im redirected to the homepage connected (the url is a little different)
I open firebug, press ctrl+f, search "eventContent" and I find the element
So...why my program doesn't find this element ?
~UPDATE~
This is the abstract websitePage Class :
public abstract class WebsitePage<T>{
private static final String BASE_URL = "http://www.test.com/";
public T openPage(Class<T> pageObject){
T page = PageFactory.initElements(getDriver(), pageObject);
getDriver().get(BASE_URL + getPageUrl());
ExpectedCondition pageLoadCondition = ((WebsitePage) page).getPageLoadCondition();
WaitForPageToLoad(pageLoadCondition);
return page;
}
private static final int LOAD_TIMEOUT = 30;
private static final int REFRESH_RATE = 2;
private void WaitForPageToLoad(ExpectedCondition pageLoadCondition) {
Wait wait = new FluentWait(getDriver())
.withTimeout(LOAD_TIMEOUT, TimeUnit.SECONDS)
.pollingEvery(REFRESH_RATE, TimeUnit.SECONDS);
}
public abstract ExpectedCondition getPageLoadCondition();
public abstract String getPageUrl();
}
~UPDATE 2~
Ive made a mistake in my com in the public class WebsiteHomePageConnected. Change :
...
System.out.println("222"); // is displayed in the console
...
to
...
System.out.println("222"); // isn't displayed in the console
...

Categories

Resources