我们在处理带有日期的 ISO 20022 消息时遇到以下困难。
考虑到这个 sese.024.001.10 消息:
<?xml version="1.0" encoding="UTF-8"?>
<DataPDU xmlns="urn:swift:saa:xsd:saa.2.0">
<Body>
<AppHdr xmlns="urn:iso:std:iso:20022:tech:xsd:head.001.001.01">
<Fr>
<FIId>
<FinInstnId>
<BICFI>DCVBCOBOXXX</BICFI> <!--BIC de la entidad que envía el mensaje-->
<Othr>
<Id>DCVBCOBOXXX</Id> <!--BIC del DCV-->
</Othr>
</FinInstnId>
</FIId>
</Fr>
<To>
<FIId>
<FinInstnId>
<BICFI>IMF1COBOXXX</BICFI> <!--BIC de la entidad que recibe el mensaje-->
<Othr>
<Id>DCVBCOBOXXX</Id> <!--BIC del DCV-->
</Othr>
</FinInstnId>
</FIId>
</To>
<BizMsgIdr>20200818X0000121</BizMsgIdr> <!--ID del mensaje-->
<MsgDefIdr>sese.024.001.10</MsgDefIdr> <!--Tipo de mensaje enviado-->
<CreDt><!--2020-08-18T09:08:30Z--></CreDt> <!--Fecha y hora de creación del mensaje-->
</AppHdr>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:sese.024.001.10">
<SctiesSttlmTxStsAdvc>
<TxId>
<AcctOwnrTxId>115</AcctOwnrTxId><!--Referencia de transacción informada en el tag TxId del mensaje sese.023-->
<AcctSvcrTxId>20200818T00052360</AcctSvcrTxId><!--Referencia única de la transacción en el DCV-->
</TxId>
<MtchgSts>
<Mtchd>MACH</Mtchd><!--Indicador de que la transacción se encuentra emparejada-->
</MtchgSts>
<TxDtls>
<TradDt>
<Dt>
<DtTm>2020-08-18T08:01:30</DtTm><!--Fecha y hora de negociación informada en el mensaje sese.023-->
</Dt>
</TradDt>
</TxDtls>
</SctiesSttlmTxStsAdvc>
</Document>
</Body>
</DataPDU>
我们尝试使用 Prowide 这样创建一个 JSon 对象:
MxSese02400110 prowideFuncional=MxSese02400110.parse(消息); System.out.println(prowideFunctional.toJson());
但是每次调用 toJson() 方法时,我们都会得到异常 Unable to make public com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl()accessible: module java.xml does not "exports com.sun.org.apache.xerces.internal.jaxp.datatype”到未命名模块
只有当 XML 上有任何日期时才会发生这种情况。
如果我删除它们,将它们留空或注释它们(在本例中为标签 DtTm 和 CreDt),异常就会消失。
你能帮我吗?
问题不在于您输入的消息。问题在于
MxSese02400110
类和包含它的库。
该库(或其使用的库;没有堆栈跟踪,很难确定)愚蠢地依赖内部 Java SE 类的反射。这从来都不合适,Sun/Oracle 一直建议程序员永远不要这样做。过去几年,Java 编译器已针对此类代码发出警告。 (我不明白为什么库在这种情况下这样做;有用于创建 XMLGregorianCalendar 对象的公共工厂方法,这根本不需要反射黑客。)
理想的解决方案是让供应商修复他们的代码。但我猜这不是一个现实的选择。
您必须向您的程序添加一些 JVM 选项。
您应该能够通过使用命令行选项
--add-exports java.xml/com.sun.org.apache.xerces.internal.jaxp.datatype=ALL-UNNAMED
强制Java的内部模块可供其他类访问来修复它。我认为不可能在运行时在代码中执行此操作,但我可能是错的。
您可能还需要open模块,以允许
MxSese02400110
类访问Java SE模块的内部类。这可以通过额外的命令行选项来完成:--add-opens java.xml/com.sun.org.apache.xerces.internal.jaxp.datatype=ALL-UNNAMED
(请注意,它是 --add-opens
,与第一个选项 --add-exports
不同。)
总而言之,如果您从终端或命令窗口运行程序,则需要在运行
java
或 java.exe
(或 javaw.exe
)时添加这些选项:
--add-exports java.xml/com.sun.org.apache.xerces.internal.jaxp.datatype=ALL-UNNAMED
--add-opens java.xml/com.sun.org.apache.xerces.internal.jaxp.datatype=ALL-UNNAMED
如果您从 GlassFish、JBoss、Tomcat 等容器运行,则需要修改该容器的启动脚本并向其中添加这些 JVM 选项。