Looking to extend inner classes in Groovy - groovy

I'm looking to extend an inner class in Groovy, it's part of a mix-in pattern that needs a groovy calculation method to be added after class construction but natively use the accessors of the main class. Works in Java, not so much in Groovy. Help appreciated.
p.s. realize that with { } groovy construct may be an alternative... trying to get this to work
Base class (in Java):
public class JavaClass {
private String foo = "Foo";
private Calculation calculation;
public JavaClass() {
calculation = new Calculation();
}
public JavaClass(Calculation calculation) {
this.calculation = calculation;
}
public String getFoo() {
return foo;
}
public String getBar() {
return calculation.getBar();
}
public class Calculation {
public String getBar() {
return null;
}
}
}
I create a Groovy implementation: (I know it's a bit hokey, bear with me)
class GroovyCalculationClass extends JavaClass {
public GroovyCalculationClass() { }
public Calculation getCalculation() {
return new Calculation();
}
public class Calculation extends JavaClass.Calculation {
public String getBar() {
return getFoo() + "Bar";
}
}
}
Run this test:
class TestCalculation {
#Test
public void testCalculation() {
JavaClass javaClass = new JavaClass(
new GroovyCalculationClass().getCalculation());
Assert.assertEquals("FooBar", javaClass.getBar());
}
}
And get this:
java.lang.ArrayIndexOutOfBoundsException: 0
at com.modelshop.datacore.generator.GroovyCalculationClass$Calculation.(GroovyCalculationClass.groovy)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190)
at com.modelshop.datacore.generator.GroovyCalculationClass.getCalculation(GroovyCalculationClass.groovy:12)
at com.modelshop.datacore.generator.GroovyCalculationClass$getCalculation.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
at com.modelshop.datacore.generator.TestCalculation.testCalculation(TestCalculation.groovy:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Replace GroovyCalculationClass with identical JavaCalculationClass and everything works.

Related

Mockito NullPointerException DataSourceTransactionManager.getTransaction()

I have a nullPointerException when I try mock a DataSourceTransactionManager, I just test one Method without access to DB.
Maybe I am do something wrong, but I don't know what.
TestClass
#RunWith(MockitoJUnitRunner.class)
public class VdpDirectshipDAOImplUT {
Logger logger = LoggerFactory.getLogger(getClass());
#InjectMocks
private VdpDirectshipDAOImpl dao;
#Mock
private DataSourceTransactionManager oracleTxManager;
#Mock
TransactionStatus transactionStatus;
#Mock
TransactionDefinition transactionDefinition;
#Test
public void testSubmitDSOrder() {
// given
int result = -1;
VdpDirectShipSession vdpDirectShipSession = new VdpDirectShipSession();
String vnetUserId = "10624802";
// when
try {
result = dao.submitDSOrder(vdpDirectShipSession, vnetUserId);
logger.info("result: {}", result);
} catch (DirectShipDataAccessException e) {
fail(e.getMessage());
}
// then
assertTrue("SKU invalid correction", result > 0);
}
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
oracleTxManager = Mockito.mock(DataSourceTransactionManager.class);
Mockito.when(oracleTxManager.getTransaction(transactionDefinition)).thenReturn(Mockito.mock(TransactionStatus.class));
}
}
DAO
public class VdpDirectshipDAOImpl extends SimpleJdbcDaoSupport implements
VdpDirectshipDAO {
/**
* transactionManager for Oracle Database
*/
private DataSourceTransactionManager oracleTxManager;
....
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class )
public int submitDSOrder(final VdpDirectShipSession vdpDirectshipService,
final String vnetUserId) throws DirectShipDataAccessException {
...
final TransactionDefinition def = new DefaultTransactionDefinition();
final TransactionStatus status = oracleTxManager.getTransaction(def);
...
}
}
Trace
java.lang.NullPointerException
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:317)
at com.autozone.vendornet.vdpdirectship.dao.VdpDirectshipDAOImplUT.setup(VdpDirectshipDAOImplUT.java:69)
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.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.RunBefores.evaluate(RunBefores.java:24)
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.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
I'm using Java 5, Spring 2.0, and junit 4.12 and I can't update their versions.
The correct implementation for my was the next.
#Spy
private DataSourceTransactionManager oracleTxManager;
...
oracleTxManager.setDataSource(Mockito.mock(DataSource.class, Mockito.RETURNS_MOCKS));

GroovyCastException when both #CompileStatic and #Newify are used

Why does the code below give GroovyCastException?
class Main {
public static void main(String... args) {
Test test = new Test()
}
}
#CompileStatic #Newify
class Test {
private HashMap<String, A> hashMap = [:]
public Test() {
set()
test()
}
public void test() {
hashMap.each() { String string, A a ->
a.printString()
}
}
public void set() {
hashMap.put("aaa", B.new("xxx"))
hashMap.put("bbb", B.new("yyy"))
}
}
class A {
public String string = ""
public void printString() {
println(string)
}
}
class B extends A {
public B(String string) {
this.string = string
}
}
The stacktrace is:
Exception in thread "main" org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'main.Test#543e710e' with class 'main.Test' to class 'main.A'
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:405)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:319)
at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:232)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:603)
at main.Test$_test_closure1.doCall(Main.groovy:37)
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:483)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1019)
at groovy.lang.Closure.call(Closure.java:426)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.callClosureForMapEntry(DefaultGroovyMethods.java:5226)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2107)
at main.Test.test(Main.groovy:36)
at main.Test.<init>(Main.groovy:32)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:80)
at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:60)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:235)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:239)
at main.Main.main(Main.groovy:19)
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:483)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
But when #CompileStatic is omitted, or when #Newify is omitted and B.new is replaced by new B, the code above gives no exception and runs as I expected.
The version of Groovy is 2.4.5.
It's probably a bug in groovy. You should maybe open an issue on JIRA.
If I decompile Test.test closure, I see :
public Object doCall(String string, A a) {
((A)ScriptBytecodeAdapter.castToType(((_test_closure1)this).getThisObject(), A.class))
.printString();
return null;
}
Groovy try to convert 'this' to A, not the variable a.
Without #Newify, the generation is correct :
public Object doCall(String k, A a) {
a.printString();
return null;
}

#CompileStatic gives NullPointerException

Why just annotating with #CompileStatic makes the below code to give NullPointerException?
class GroovyEach {
static def main(args) {
List items = null
items.each {
println 'hello'
}
}
}
Below code gives exception.
import groovy.transform.CompileStatic
#CompileStatic
class GroovyEach {
static def main(args) {
List items = null
items.each {
println 'hello'
}
}
}
Stacktrace:
Exception in thread "main" java.lang.NullPointerException
at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1372)
at trial.GroovyEach.main(GroovyEach.groovy:10)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
This is the inverse of an older question. When compiled statically, items is of type List, when not compiled statically the type is NullObject, which retrieves the iterator in a null-safe fashion. This is trivial to demonstrate.
This works
class GroovyEach {
static void main(String[] args) {
List items = null
(org.codehaus.groovy.runtime.NullObject) items
}
}
this fails with [Static type checking] - Inconvertible types: cannot cast java.util.List to org.codehaus.groovy.runtime.NullObject
#groovy.transform.CompileStatic
class GroovyEach {
static void main(String[] args) {
List items = null
(org.codehaus.groovy.runtime.NullObject) items
}
}

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException when setting values of new controler

I have following setup:
2 FXML-Doxuments WelcomeScreen.fxml and Timesheet.fxml with it's both controllers WelcomeScreenController.java and TimesheetController.java.
On WelcomeScreenController I have an button action handler
createTimesheet(ActionEvent event){
// Some working code
final Calendar calendarStart = Calendar.getInstance();
calendarStart.setTime(sdf.parse(tfStartDate.getText()));
final Calendar calendarEnd = Calendar.getInstance();
calendarEnd.setTime(sdf.parse(tfEndDate.getText()));
final FXMLLoader loader = new FXMLLoader(getClass().getResource("Timesheet.fxml"));
final TimesheetControler timesheetControler = (TimesheetControler)loader.getController();
timesheetControler.setStartDate(calendarStart);
timesheetControler.setEndDate(calendarEnd);
timesheetControler.setHeadlineText("Timesheet (" + tfStartDate.getText() + " - " + tfEndDate.getText() + ")");
final Node node=(Node) event.getSource();
final Stage stage=(Stage) node.getScene().getWindow();
final Parent root = (Parent) loader.load();
stage.setScene(new Scene(root));
stage.show();
}
TimesheetController looks like this:
package de.liebich.work.report.emb.ui;
public class TimesheetControler implements Initializable {
#FXML
private Label lHeadline;
#FXML
private GridPane gTimesheetCheck;
private Calendar startDate;
private Calendar endDate;
private String user;
private String password;
private String baseURL;
private List<List<Label>> entries;
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
}
public void setStartDate(Calendar startDate) {
this.startDate = startDate;
}
public void setEndDate(Calendar endDate) {
this.endDate = endDate;
}
public void setUser(String user) {
this.user = user;
}
public void setPassword(String pw) {
this.password = pw;
}
public void setBaseURL(String baseURL) {
this.baseURL = baseURL;
}
public void setHeadlineText(final String text){
lHeadline.setText(text);
}
}
When I call createTimesheet I get following error:
java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1449)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Node.fireEvent(Node.java:6867)
at javafx.scene.control.Button.fire(Button.java:179)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:193)
at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:336)
at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:329)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:64)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
at javafx.event.Event.fireEvent(Event.java:171)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3311)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3151)
at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3106)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1563)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2248)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:250)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:173)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:292)
at com.sun.glass.ui.View.handleMouseEvent(View.java:530)
at com.sun.glass.ui.View.notifyMouse(View.java:924)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:17)
at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:67)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.lang.reflect.InvocationTargetException
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 sun.reflect.misc.Trampoline.invoke(MethodUtil.java:75)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:279)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1444)
... 44 more
Caused by: java.lang.NullPointerException
at de.liebich.work.report.emb.ui.WelcomeScreenControler.createTimesheet(WelcomeScreenControler.java:133)
... 54 more
What do I have to change to make my code working?
Call
loader.load();
before the line
final TimesheetControler timesheetControler = (TimesheetControler) loader.getController();
IMO there is no need to explain the reason of it. If you still doubt ask it in comment.
using
final TimesheetControler timesheetControler = (TimesheetControler)loader.load();

JAXB : Please verify the structure for the XML to java in JAXB

This is my XML file
<BADFM>
<Given>
<Ord>
<Bag IDC="DM" />
</Ord>
</Given>
</BADFM>
This is my Parser class
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
public class Test {
public static void main(String args[]) throws Exception {
File file = new File("D:\\BADML.xml");
JAXBContext jaxbContext = JAXBContext
.newInstance(MyMessage.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MyMessage authentifyResult = (MyMessage) jaxbUnmarshaller
.unmarshal(file);
System.out.println(authentifyResult.getGiven().getOrd().getBag().getIDC());
}
}
This is MyMessage
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="BADFM")
public class MyMessage
{
#XmlElement(name="Given")
private Given given;
public Given getGiven() {
return given;
}
public void setGiven(Given given) {
this.given = given;
}
}
This is Given.java
import javax.xml.bind.annotation.XmlElement;
public class Given {
private Ord ord;
#XmlElement(name = "Ord")
public Ord getOrd() {
return ord;
}
public void setOrd(Ord ord) {
this.ord = ord;
}
}
This is Ord.java
import javax.xml.bind.annotation.XmlElement;
public class Ord {
private Bag bag;
#XmlElement(name="Bag")
public Bag getBag() {
return bag;
}
public void setBag(Bag bag) {
this.bag = bag;
}
}
This is Bag.java
import javax.xml.bind.annotation.XmlAttribute;
public class Bag {
#XmlAttribute(name="IDC")
private String IDC ;
public String getIDC() {
return IDC;
}
#XmlAttribute(name="IDC")
public void setIDC(String IDC) {
IDC = IDC;
}
}
When i ran that i am getting
Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "IDC"
this problem is related to the following location:
at public java.lang.String Bag.getIDC()
at Bag
at public Bag Ord.getBag()
at Ord
at public Ord Given.getOrd()
at Given
at public Given MyMessage.getGiven()
at MyMessage
this problem is related to the following location:
at private java.lang.String Bag.IDC
at Bag
at public Bag Ord.getBag()
at Ord
at public Ord Given.getOrd()
at Given
at public Given MyMessage.getGiven()
at MyMessage
at com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Builder.check(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)
at com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(Unknown Source)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
at com.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.xml.bind.ContextFinder.newInstance(Unknown Source)
at javax.xml.bind.ContextFinder.find(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at Test.main(Test.java:11)
You need to use the #XmlAttribute for the IDC variable of the Bag class. Once you make that change, the XML you referenced at the top will work.
As for your current code, it is expecting the XML to look like:
<Bag>
<IDC>DM</IDC>
</Bag>
You can easily see what type of XML your classes are expecting by populating all attribute fields and then marshaling the object to a file.
Update
You should always declare your attributes as private if you are going to have properly named getters and setters. Otherwise, JAXB will throw the error Class has two properties of the same name.
When declaring that a class attribute is a #XmlAttribute, you should also put the annotation on the getter so that JAXB does not think you want both a #XmlAttribute and #XmlElement with the same name.
public class Bag {
private String IDC ;
#XmlAttribute(name="IDC")
public String getIDC() {
return IDC;
}
public void setIDC(String IDC) {
this.IDC = IDC;
}
}

Resources