Infinispan deserialization white list : Class '[I' - java

I am using Infinispan alongside hibernate on my project and I encountered a strange error log:
ISPN000936: Class '[I' blocked by deserialization white list. Adjust the configuration serialization white list regular expression to include this class
I already have this issue but with normal class name so I could resolve the problem by adding the class to the serialization white-list like this:
globalConfigurationBuilder
.serialization()
.marshaller(new JavaSerializationMarshaller())
.whiteList()
.addClass(MyClass.class.getName());
but with this strange class name ('[I') I can't do this.
I can solve the problem by authorizing all the class in the serialization white-list like this :
globalConfigurationBuilder
.serialization()
.marshaller(new JavaSerializationMarshaller())
.whiteList()
.addRegexp(".*");
But I would like handle the problem in a more proper way.
Does someone have encountered the same issue and managed to solved it ?

[I is the internal name for an int[], so you can use any of the following:
.addClass​("[I")
.addClass​(int[].class.getName())
.addClasses(int[].class)
When you have more than one, I'd use the last one, which is a vararg method, e.g.
.addClasses(MyClass.class,
FooClass.class,
BarClass.class,
int[].class)

Related

Spring Integration - object placed in header is returned as String rather than the object type

I've got an integration flow written in the Java DSL
I'm enriching the header of a message to include an AtomicInteger:
.enrichHeaders(t -> t.headerFunction(pollTime,message -> new AtomicInteger()))
If I put a breakpoint on the subsequent handle method in the same flow I can see the header and it's a String not an AtomicInteger.
So if I try to retrieve it in another flow like so I get an illegal argument exception:
message.getHeaders().get(pollTime,AtomicInteger.class).getAndAdd(delay);
Caused by: java.lang.IllegalArgumentException: Incorrect type specified for header 'pollTime'. Expected [class java.util.concurrent.atomic.AtomicInteger] but actual type is [class java.lang.String]
If I do the same thing in the Kotlin DSL it all works fine:
enrichHeaders {
headerFunction<Any>(pollCount) {
AtomicInteger()
}
}
Does anyone have any idea of what I am doing wrong ?
I created a stand alone project to reproduce the error, and that added in the header as an expected AtomicInteger.
Then I debugged our main application and it turns out there's an OpenTracingChannelInterceptor which is re-writing all headers as Strings.
This library is the culprit:
io.opentracing.contrib:opentracing-spring-messaging:0.0.5 which is transitive dependency of io.opentracing.contrib:opentracing-spring-cloud-starter-jaeger
It looks like adding this library just breaks Spring Integration.
The fix is to exclude the tracing autoconfiguration:
#SpringBootApplication(exclude = {OpenTracingChannelInterceptorAutoConfiguration.class})
Update:
The opentracing library is now longer maintained so the long term fix for this would be to migrate to a different tracing library that hopefully doesn't have the same type of issue.
See
https://www.cncf.io/blog/2022/01/31/cncf-archives-the-opentracing-project/

jaxb and serializable from marshalling server.xml for tomcat server

I need to extract server.xml from tomcat server for got it updated automatically.
I create xsd file from file but now instead turn me the classical bean it return me a List.
In this list i got 2 different element: ResourceType and ManagerType.
How i can cast them to appropriate Class?
I've tried with casting to class (ignoring exception!) but it doesnt work...
I've tried with 'instance of' but it doesnt work...
I've tried with unmarshalling with jaxb method but there is no way to cast serializable to InputStream...
I've run out of ideas.
I see that at runtime the object serializable contain the name of class (ResourceType for instance), but i dont find the way to get it out...
Someone has suggestions?
The solution was to cast serializable object to JAXBElement<T> where T is class i was searching for (JAXBElement<ManagerType> for instance).

Axis2 error: Invalid white space character (0x4) in text to output

I have created a Java client to interact with a SOAP webservice using Axis2 (1.7.6) as code generator. The problem is with some inputs the client is throwing an exception with the message:
org.apache.axis2.AxisFault: Invalid white space character (0x4) in text to output (in xml 1.1, could output as a character entity)
It seems the serialiser is hitting some chars considered invalid to XML spec. I have seen that problem around but no definitive answer or the fix. I'm not using Spring or any other dependency injection framework, it's a standalone application, so I need to configure the inners of Axis2 by hand.
Any ideas on how to fix/configure the client properly?
After some research I found this behaviour is due to one default setting of the lib Woodstox (Axis2 dependency), that uses the class com.ctc.wstx.api.InvalidCharHandler.FailingHandler as default implementation of the interface com.ctc.wstx.api.InvalidCharHandler, used inside com.ctc.wstx.sw.XmlWriter and invoked in the serialisation process. This means: when the component hits characters considered invalid to XML, it’ll throw an error.
Woodstox provides another implementation of the interface com.ctc.wstx.api.InvalidCharHandler, the one called com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler that instead of throwing errors will replace those chars for something else. But how to do that?
The class com.ctc.wstx.stax.WstxOutputFactory inside Woodstox contains several configurations, one of them being the invalid char handler. Though, it's not configurable by some magic system wide property, instead, by the method com.ctc.wstx.stax.WstxOutputFactory#setProperty, that takes as arguments one string and one object.
So first, you'll have to extend that factory and set the property com.ctc.wstx.outputInvalidCharHandler with an instance of com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler that takes as argument the char you want to replace the invalid ones with. Like this:
package my.package;
import com.ctc.wstx.stax.WstxOutputFactory;
public class MyWstxOutputFatory extends WstxOutputFactory {
public MyWstxOutputFatory() {
setProperty(
com.ctc.wstx.api.WstxOutputProperties.P_OUTPUT_INVALID_CHAR_HANDLER,
new com.ctc.wstx.api.InvalidCharHandler.ReplacingHandler(' '));
}
}
The second, trickiest and undocumented step is how to register your implementation as the factory Woodstox'll use. You'll have to create a file named META-INF/services/javax.xml.stream.XMLOutputFactory simply containing the name of your factory, in this case, the string:
my.package.MyWstxOutputFatory
Place this file in such a way it's included in your project's resulting jar. In my case I placed like: src/main/resources/META-INF/services/javax.xml.stream.XMLOutputFactory.
And you're done!

How can I map a PostgreSQL varchar[] (array column) to a List<String> in Java using Hibernate?

I have a column in PostgreSQL 9.6 of type "character varying[]" which is essentially an array of strings. I am using Dropwizard with Hibernate to handle the database connection. Normally I just need to provide an annotation to define the data type, however, Hibernate is complaining about the deserialization of a varchar[] type. How do I map this to a List in Java?
I have tried implement my own UserType extended class to handle the (de)serialization with no luck. Any help would be most appreciated.
UPDATE:
I took a look at this link posted by #Waqas and I was able to at least create a type that extends UserType to implement the mapping of varchar[] to String[] in Java.
Some differences in my implementation:
In the nullSafeSet() and nullSafeGet() methods that need to be implemented (#Override), I had to use a (newer?) class called SharedSessionContractImplementor from org.hibernate.engine.spi instead of the (older?) class SessionImplementor.
When I implemented this change and added the #Type annotation to my column mapping (in my entity data class) my runtime was complaining about an #Override that apparently wasn't valid for a certain HibernateBundle class (error below). Even though maven built the jar without any issues and I only have Java 1.8 installed on my machine (OpenSuse). P.S. I am using Dropwizard 1.2 and I took the declaration of the HibernateBundle straight from their documentation. Nevertheless, I deleted the #Override annotation and it works now. Not sure why, or how, but it does.
Error as promised:
INFO [2017-11-08 22:39:06,220] org.eclipse.jetty.util.log: Logging initialized #1137ms to org.eclipse.jetty.util.log.Slf4jLog
INFO [2017-11-08 22:39:06,310] io.dropwizard.server.DefaultServerFactory: Registering jersey handler with root path prefix: /
INFO [2017-11-08 22:39:06,312] io.dropwizard.server.DefaultServerFactory: Registering admin handler with root path prefix: /
java.lang.Error: Unresolved compilation problem:
The method getDataSourceFactory(ApplicationConfiguration) of type new HibernateBundle<ApplicationConfiguration>(){} must override a superclass method
at com.tksoft.food.Application$1.getDataSourceFactory(Application.java:24)
at com.tksoft.food.Application$1.getDataSourceFactory(Application.java:1)
at io.dropwizard.hibernate.HibernateBundle.run(HibernateBundle.java:61)
at io.dropwizard.hibernate.HibernateBundle.run(HibernateBundle.java:15)
at io.dropwizard.setup.Bootstrap.run(Bootstrap.java:200)
at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:42)
at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:85)
at io.dropwizard.cli.Cli.run(Cli.java:75)
at io.dropwizard.Application.run(Application.java:93)
at com.tksoft.food.Application.main(Application.java:30)
Any way, this has left me super confused, but it is working so I am happy :) (for now). I just have to figure out if I can map it to a List instead of an array :/

Injecting list of generics in Spring 4.1

The following issue was encountered while upgrading Spring 3.2 -> 4.1
There is a Metadata hierarchy, like: AMetadata extends Metadata,
BMetadata extends Metadata etc.
There is a Processor hierarchy, like:
abstract Processor<M extends Metadata>,
AProcessor extends Processor<AMetadata>,
BProcessor extends Processor<BMetadata> etc
There is a service containing an injected List of processors, like this:
#Inject
private List<Processor<Metadata>> processors;
While this worked perfectly in Spring 3.2, with Spring 4.1.0 (and 4.0 as well) it fails to inject list members. Going into debug, it was discovered that:
Processor<Metadata>.isAssignableFrom(BProcessor) == false and this causes Processor beans not to be matched as eligible candidates for injection.
A possible hack-looking solution is to declare Processors as follows:
BProcessor<Metadata> extends Processor<BMetadata> - that works, but looks a bit weird. Another option is to use List<Processor<? extends Metadata>>, but this requires some code changes elsewhere to be compilable and causes a lot of type-safety-check warnings in classes which relied on generics.
So the question is, how to handle this case properly? Did anyone encountered something similar?
Autowiring based on generics was one of the new features in Spring4. AFAIK they were ignored in previous versions. More info here: https://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics
So I can't think of any other solution than you already pointed out: List<Processor<? extends Metadata>>.
Also see video here Spring Framework on Java 8 https://www.youtube.com/watch?v=-_aWK8T_YMI that explains this. Generic type information was ingored till 4.0 Spring release. Now, they are taking into account.

Categories