Why do I get the exception "Found ambiguous parameter type"? Spring Batch Integration - spring-integration

I am learning Spring Batch Integration from here and I know how to launch a job when a message is received. Now, I wanted to get both the name and path of the message (which is a file). Below are my working codes. However, if I uncomment the setFileParameterName method, then I get the following exception:
java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
Why does this exception occur? The message makes no sense to me. I pass in a String and it is somehow confused between the two methods, but one of them takes in a String and the other a Job? Any help with this is appreciated.
FileMessageToJobRequest.java
public class FileMessageToJobRequest {
private String filePathParameterName;
private Job job;
private String fileParameterName;
public void setFilePathParameterName(String filePathParameterName) {
this.filePathParameterName = filePathParameterName;
}
public void setJob(Job job) {
this.job = job;
}
// public void setFileParameterName(String fileParameterName) {
// this.fileParameterName = fileParameterName;
// }
#Transformer
public JobLaunchRequest toRequest(Message<File> message) throws IOException {
JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
// jobParametersBuilder.addString(fileParameterName, message.getPayload().getName());
jobParametersBuilder.addString(filePathParameterName, message.getPayload().getCanonicalPath());
jobParametersBuilder.addDate("dummy", new Date()); // need to add at least one unique identifier so that it will run more than once
return new JobLaunchRequest(job, jobParametersBuilder.toJobParameters());
}
}
BatchIntegrationConfiguration.java
#Configuration
#EnableIntegration
#EnableBatchProcessing
public class BatchIntegrationConfiguration {
#Autowired
private JobBuilderFactory jobBuilderFactory;
#Autowired
private StepBuilderFactory stepBuilderFactory;
#Autowired
private JobRepository jobRepository;
#Bean
public MessageChannel files() {
return new DirectChannel();
}
#Bean
public FileMessageToJobRequest fileMessageToJobRequest() {
FileMessageToJobRequest fileMessageToJobRequest = new FileMessageToJobRequest();
// fileMessageToJobRequest.setFileParameterName("input.file.name")
fileMessageToJobRequest.setFilePathParameterName("input.file.path");
fileMessageToJobRequest.setJob(runBatchScriptJob());
return fileMessageToJobRequest;
}
#Bean
public JobLaunchingGateway jobLaunchingGateway() {
SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
simpleJobLauncher.setJobRepository(jobRepository);
simpleJobLauncher.setTaskExecutor(new SyncTaskExecutor());
JobLaunchingGateway jobLaunchingGateway = new JobLaunchingGateway(simpleJobLauncher);
return jobLaunchingGateway;
}
#Bean
public IntegrationFlow integrationFlow(JobLaunchingGateway jobLaunchingGateway) {
return IntegrationFlows.from(Files.inboundAdapter(new File("./src/main/resources")).
filter(new SimplePatternFileListFilter("simplebatchfile.bat")),
c -> c.poller(Pollers.fixedRate(10000).maxMessagesPerPoll(1))).
handle(fileMessageToJobRequest()).
handle(jobLaunchingGateway).
log(LoggingHandler.Level.WARN, "headers.id + ': ' + payload").
get();
}
#Bean
public Job runBatchScriptJob() {
return jobBuilderFactory.get("runBatchScriptJob")
.listener(new JobCompletionNotificationListener())
.start(runBatchScriptStep())
.build();
}
#Bean
public Step runBatchScriptStep() {
return stepBuilderFactory.get("runBatchScriptStep")
.tasklet(runBatchScriptTasklet(null))
.build();
}
#Bean
#StepScope
public Tasklet runBatchScriptTasklet(#Value("#{jobParameters['input.file.path']}") String filePath) {
RunBatchScriptTasklet tasklet = new RunBatchScriptTasklet();
tasklet.setFilePath(filePath);
return tasklet;
}
}
StackTrace
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'integrationFlow' defined in class path resource [com/example/batchprocessing/BatchIntegrationConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'integrationFlow' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) [spring-boot-2.2.5.RELEASE.jar:2.2.5.RELEASE]
at com.example.batchprocessing.BatchProcessingApplication.main(BatchProcessingApplication.java:14) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.integration.dsl.IntegrationFlow]: Factory method 'integrationFlow' threw exception; nested exception is java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 18 common frames omitted
Caused by: java.lang.IllegalArgumentException: Found ambiguous parameter type [class java.lang.String] for method match: [public void com.example.batchprocessing.FileMessageToJobRequest.setFileParameterName(java.lang.String), public void com.example.batchprocessing.FileMessageToJobRequest.setJob(org.springframework.batch.core.Job)]
at org.springframework.util.Assert.isNull(Assert.java:176) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.validateFallbackMethods(MessagingMethodInvokerHelper.java:755) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.findHandlerMethodsForTarget(MessagingMethodInvokerHelper.java:740) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:294) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:231) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.<init>(MessagingMethodInvokerHelper.java:225) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.MethodInvokingMessageProcessor.<init>(MethodInvokingMessageProcessor.java:62) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.handler.ServiceActivatingHandler.<init>(ServiceActivatingHandler.java:39) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.BaseIntegrationFlowDefinition.handle(BaseIntegrationFlowDefinition.java:960) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:510) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:65) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.BaseIntegrationFlowDefinition.handle(BaseIntegrationFlowDefinition.java:939) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:503) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:65) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.BaseIntegrationFlowDefinition.handle(BaseIntegrationFlowDefinition.java:926) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.integration.dsl.IntegrationFlowDefinition.handle(IntegrationFlowDefinition.java:498) ~[spring-integration-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.example.batchprocessing.BatchIntegrationConfiguration.integrationFlow(BatchIntegrationConfiguration.java:78) ~[classes/:na]
at com.example.batchprocessing.BatchIntegrationConfiguration$$EnhancerBySpringCGLIB$$238a9f8a.CGLIB$integrationFlow$1(<generated>) ~[classes/:na]
at com.example.batchprocessing.BatchIntegrationConfiguration$$EnhancerBySpringCGLIB$$238a9f8a$$FastClassBySpringCGLIB$$b8a5aaf.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.4.RELEASE.jar:5.2.4.RELEASE]
at com.example.batchprocessing.BatchIntegrationConfiguration$$EnhancerBySpringCGLIB$$238a9f8a.integrationFlow(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_211]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_211]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_211]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.4.RELEASE.jar:5.2.4.RELEASE]
... 19 common frames omitted

This one handle(fileMessageToJobRequest()) has to be changed to the transform(fileMessageToJobRequest()) since your FileMessageToJobRequest is really a #Transformer. The handle() doesn't understand that annotation and tries to figure out any candidate method to execute at runtime.
The message Found ambiguous parameter type means that there are several methods with different parameters which can be as message handling candidates. In this case we need to be more specific. Like your #Transformer is a good marker, but it is used from the wrong place - the handle() is for a #ServiceActivator.

Related

Not able insert through jpa outbound gateway

#Bean
public IntegrationFlow reimInvJpaOutbound() {
return IntegrationFlows
.from("reimInvProcessChannel")
.handle(reimJpaHandlers.reimStgInsertJpaHandler())
.log()
.get();
}
#Component
#Transactional
public class ReIMJpaHandlers {
Logger logger = LoggerFactory.getLogger(this.getClass());
#PersistenceContext
protected EntityManager entityManager;
#Autowired
ReIMHistInvHdrStgRepository histRepo;
#Autowired
ReIMInvHdrStgRepository stgRepo;
#Autowired
ReIMErrInvHdrStgRepository errRepo;
String responseQueryString = "select * from RMS16DEV.TSC_IM_DOC_HEAD_TEMP where error_ind != null";
#Bean
public JpaUpdatingOutboundEndpointSpec reimStgInsertJpaHandler() {
System.out.println("Writing to reim stg");
return Jpa
.updatingGateway(entityManager)
.entityClass(TSC_IM_DOC_HEAD_TEMP.class)
;
}
#Bean
public JpaPollingChannelAdapter reimStgResponseJpaInboundAdapter() {
return Jpa
.inboundAdapter(entityManager)
.nativeQuery(responseQueryString)
.maxResults(100)
.get();
}
}
But I am getting below error:
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'merge' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:292) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at com.sun.proxy.$Proxy189.merge(Unknown Source) ~[na:na]
Your
#Component
#Transactional
public class ReIMJpaHandlers {
doesn't matter for the
#Bean
public JpaUpdatingOutboundEndpointSpec reimStgInsertJpaHandler() {
The last one is a bean and it lives in its own lifecycle and all its method calls are happened already outside of your #Transactional on the ReIMJpaHandlers.
You need to consider to configure a TX manager exactly for the .handle(reimJpaHandlers.reimStgInsertJpaHandler()):
.handle(reimJpaHandlers.reimStgInsertJpaHandler(), e -> e.transactional())
assuming that you have a bean with the transactionManager name.
The #Transactional on the class is applied for the business methods, but not #Bean methods which are called only once when we create a bean.

#EJB is null in #ManagedBean

I am very new to the web application development. I am trying to implement an EJB call to my ManagedBean method from JSF command button.
here is sample code:
JSF :
<h:commandButton value="CommandButton" action="#{someBean.someBeanMethod}" />
ManagedBean :
#ManagedBean
#ViewScoped
public class SomeBeanClient implements Serializable {
private static final long serialVersionUID = 1L;
#EJB
private Service service ;
public String someBeamMethod() throws NamingException {
final Future<String> red = service.someAsyncMethod();
service.someSyncMethod();
return "DummyValue";
}
}
EJB Class :
#Stateless
public class Service {
#Asynchronous
public Future<String> someAsyncMethod(){
try {
System.out.println("Gd nyt");
Thread.sleep(10000);
System.out.println("Gd mrning");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new AsyncResult<String>("success");
}
public void someSyncMethod(){
System.out.println("Gd Day");
}
}
Expecting S.O.P in following order :
Gd nyt
Gd Day
Gd mrning
Actual Result:
servlet E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause Faces Servlet: javax.servlet.ServletException: Error calling action method of component with id paneForm:content:PushToGIT:_idJsp72:_idJsp165
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:154)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1225)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:775)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:457)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.invokeTarget(WebAppFilterChain.java:136)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:97)
at ilog.rules.teamserver.web.security.SecurityCheckPointFilter.doFilter(SecurityCheckPointFilter.java:112)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:195)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:91)
at ilog.rules.teamserver.web.servlets.filter.IlrAccessFilter.doFilter(IlrAccessFilter.java:199)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:195)
Caused by: javax.faces.el.EvaluationException: Exception while invoking expression #{someBean.someBeanMethod}
at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:156)
at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:61)
... 49 more
Caused by: java.lang.NullPointerException
at com.tiaa.brms.ejb.SomeBeanClient.someBeanMethod(SomeBeanClient.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:607)
at org.apache.myfaces.el.MethodBindingImpl.invoke(MethodBindingImpl.java:132)
... 50 more

I use #Resource, #Bean to inject bean, but sometimes the wrong bean gets injected

I use #Resource, #Bean to inject bean, But sometimes wrong bean injection. Why this?
-------- throw Exception
java.lang.ClassCastException: com.test.B cannot be cast to com.test.A at
com.test.ModelA.handle(ModelA.java:35) at
com.test.ModelA.handle(ModelA.java:35) at
com.test.AbstractModel.execute(AbstractRule.java:12) at
com.test.AbstractModel.execute(AbstractRule.java:9) at
com.test.modelChain.execute(modelChain.java:35) at
com.test.BManager.process(BManager.java:66) at
com.test.BManager.process(BManager.java:31) at
sun.reflect.GeneratedMethodAccessor121.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at
java.lang.reflect.Method.invoke(Method.java:606) at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at
org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) at
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) at
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) at
com.sun.proxy.$Proxy41.process(Unknown Source) at
-----AConfig.class--------------------------------------------------
#Configuration
public class AConfig<T>{
#Autowired
private Model<T> modelA;
#Autowired
private Model<T> modelB;
#Bean
public List<Model<T>> getAModelList(){
List<Model<T>> lists = new ArrayList<Model<T>>();
lists.add(modelA);
return lists;
}
#Bean
public List<Model<T>> getBModelList(){
List<Model<T>> lists = new ArrayList<Model<T>>();
lists.add(modelB);
return lists;
}
}
-----AManager.class--------------------------------------------
#Component
public class AManager implements Manager<AA>{
#Autowired
private ModelChain<AA> modelChain;
#Resource(name="getAModelList")
private List<Model<AA>> aModelList;
public void process(){
modelChain.setModelList(aModelList);
// process Logic to use aModelList
}
}
-----BManager.class--------------------------------------------------
#Component
public class BManager implements Manager<BB>{
#Autowired
private ModelChain<BB> modelChain;
#Resource(name="getBModelList")
private List<Model<BB>> bModelList;
public void process(){
modelChain.setModelList(bModelList);
// process Logic to use bModelList
}
}

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;
}
}

how to overcome"java.sql.Clob is an interface, and JAXB can't handle interfaces" issue

I am making an jaxbcontext newInstance, passing DO as a class.My DO contains java.sql.clob as one of the fields.
This clob field is creating an issue while creating a new Instance. Giving error as
Exception occured While capturing clob
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
java.sql.Clob is an interface, and JAXB can't handle interfaces.
this problem is related to the following location:
at java.sql.Clob
at public java.sql.Clob com.data.subscriber.SubscriberProvTransDO.getXmlString()
at com.data.subscriber.SubscriberProvTransDO
The type of the getter is java.io.InputStream but that of the setter is long. They have to be the same.
this problem is related to the following location:
at public abstract java.io.InputStream java.sql.Clob.getAsciiStream() throws java.sql.SQLException
at java.sql.Clob
at public java.sql.Clob com.data.subscriber.SubscriberProvTransDO.getXmlString()
at com.data.subscriber.SubscriberProvTransDO
this problem is related to the following location:
at public abstract java.io.OutputStream java.sql.Clob.setAsciiStream(long) throws java.sql.SQLException
at java.sql.Clob
at public java.sql.Clob com.data.subscriber.SubscriberProvTransDO.getXmlString()
at com.data.subscriber.SubscriberProvTransDO
The type of the getter is java.io.Reader but that of the setter is long. They have to be the same.
this problem is related to the following location:
at public abstract java.io.Reader java.sql.Clob.getCharacterStream() throws java.sql.SQLException
at java.sql.Clob
at public java.sql.Clob com.data.subscriber.SubscriberProvTransDO.getXmlString()
at com.data.subscriber.SubscriberProvTransDO
this problem is related to the following location:
at public abstract java.io.Writer java.sql.Clob.setCharacterStream(long) throws java.sql.SQLException
at java.sql.Clob
at public java.sql.Clob com.data.subscriber.SubscriberProvTransDO.getXmlString()
at com.data.subscriber.SubscriberProvTransDO
at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:66)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:389)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:236)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:618)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:210)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:368)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at com.business.system.handler.EventProcessorHandler.insertFailure(EventProcessorHandler.java:286)
at com.business.system.handler.EventProcessorHandler.processRequest(EventProcessorHandler.java:184)
at com.business.system.EventProcessorBean.onMessage(EventProcessorBean.java:51)
at com.ibm.ejs.container.MessageEndpointHandler.invokeMdbMethod(MessageEndpointHandler.java:1086)
at com.ibm.ejs.container.MessageEndpointHandler.invoke(MessageEndpointHandler.java:773)
at $Proxy6.onMessage(Unknown Source)
at com.ibm.ws.sib.api.jmsra.impl.JmsJcaEndpointInvokerImpl.invokeEndpoint(JmsJcaEndpointInvokerImpl.java:201)
at com.ibm.ws.sib.ra.inbound.impl.SibRaDispatcher.dispatch(SibRaDispatcher.java:768)
at com.ibm.ws.sib.ra.inbound.impl.SibRaSingleProcessListener$SibRaWork.run(SibRaSingleProcessListener.java:584)
at com.ibm.ejs.j2c.work.WorkProxy.run(WorkProxy.java:419)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1469)
You could use an XmlAdapter for this use case. The XML adapter will convert the unmappable object java.sql.Clob to a mappable object such as String:
ClobAdapter
import java.sql.Clob;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class ClobAdapter extends XmlAdapter<String, Clob> {
#Override
public Clob unmarshal(String v) throws Exception {
// Convert String to Clob
}
#Override
public String marshal(Clob v) throws Exception {
// Convert Clob to String
}
}
Root
The #XmlJavaTypeAdapter must be set on the Clob property. This annotation is how you link in the XmlAdapter:
import java.sql.Clob;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class Root {
private Clob clob;
#XmlJavaTypeAdapter(ClobAdapter.class)
public Clob getClob() {
return clob;
}
public void setClob(Clob clob) {
this.clob = clob;
}
}
Demo
import javax.xml.bind.JAXBContext;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
}
}
For More Information
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
http://bdoughan.blogspot.com/2011/05/jaxb-and-joda-time-dates-and-times.html

Resources