question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[FEATURE REQ] Provide a way to specify the XMLInputFactory to use to the XMLMapper of JacksonAdapter

See original GitHub issue

Is your feature request related to a problem? Please describe. The Azure Data Lake Storage Gen2 BlobServiceClient.listBlobContainers() call falls into an infinite loop in my project, which already has an older version of woodstox-5.0.3.jar on the classpath that cannot be removed. With the older woodstox library, the NextMarker attribute is not deserialized properly into the BlobContainersSegment model. The value gets deserialized as “” (empty String) instead of null when the list is exhausted. The PageableIterable interprets the empty String as “start from the beginning”, and successive calls to next() make additional requests to Azure listing the contents in an infinite loop.

Describe the solution you’d like I would like a way to expose alternative constructors of XmlMapper used in JacksonAdapter to developers (maybe through an SPI) so I can specify the correct XMLInputFactory (the one for woodstox-6.0.2 that is a transitive dependency of azure-core) used by the XmlFactory instead of the default behavior, which uses javax.xml.stream.XMLInputFactory.newInstance() resolving to the wrong woodstox library.

An SPI wouldn’t be required, maybe the call in JacksonAdapter could be modified to specify a new XMLMapper( new com.ctc.wstx.stax.WstxInputFactory() ). I could then simply shade the Azure dependencies following what has been previously suggested for jackson to avoid all conflicts.

Describe alternatives you’ve considered I have rebuilt jackson-dataformat-xml and modified the XmlMapper() constructor to use the constructor. However, I don’t really care for building and distributing a custom jackson-dataformat-xml library.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:17 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
cbismuthcommented, Nov 27, 2021

Same issue here: before upgrading to the latest Azure SDK the EventHubTrigger function argument type was of type String, but after upgrading it is now of type List<Map<String, String>>.

To avoid shading Maven dependencies, we serialize/deserialize the input object as shown below, with a little CPU overhead.

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.microsoft.azure.functions.annotation.Cardinality;
import com.microsoft.azure.functions.annotation.EventHubTrigger;
import com.microsoft.azure.functions.annotation.FunctionName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;

public class SampleFunction {

    private static final Logger LOGGER = LoggerFactory.getLogger(SampleFunction.class);

    private static final Gson GSON = new GsonBuilder().create();

    private static <T> T[] fromObject(final Object input, final Class<T[]> classOfT) {
        final String json = GSON.toJson(input);

        return GSON.fromJson(json, classOfT);
    }

    private static class MyEventType {
        // Implementation goes here ...
    }

    @FunctionName("sampleFunction")
    public void consumeViewedVideoCassandraFunctionEvents(@EventHubTrigger(name = "name",
                                                                           eventHubName = "eventHubName",
                                                                           consumerGroup = "consumerGroup",
                                                                           connection = "connection",
                                                                           cardinality = Cardinality.MANY) final Object input) {
        try {
            final MyEventType[] objects = fromObject(input, MyEventType[].class);

            Arrays.stream(objects)
                  .forEach(object -> {
                      // Implementation goes here ...
                  });
        } catch (final Throwable e) {
            LOGGER.error(e.getMessage(), e);

            throw e;
        }
    }
}
1reaction
jonjarviscommented, May 16, 2020

@anuchandy - Thank you for the extra references. I’m trying to avoid using OSGi in general though. I was able to restructure my maven build (I created a module to generate the shaded jar for azure datalake and azure identity) as suggested using the shade plugin to relocate the stax-api for javax.xml.stream used by jackson-dataformat-xml. I like this solution better than rebuilding jackson-dataformat-xml, so thank you for the suggestion/example.

While this works, I still have reservations shading all the dependencies into an uber jar (and then explaining the two seemingly random System.setProperty calls). Its not urgent, but I think it would be good to offer developers a way to customize the way azure-core creates the JacksonAdapter.

Read more comments on GitHub >

github_iconTop Results From Across the Web

XMLInputFactory (Java Platform SE 8 ) - Oracle Help Center
This static method creates a new factory instance. This method uses the following ordered lookup procedure to determine the XMLInputFactory implementation class ...
Read more >
java.lang.LinkageError: Package versions: jackson-core=2.13 ...
The error occurs if there are multiple versions of Jackson on the dependency list. Azure SDK libraries aggressively update Jackson version ...
Read more >
Solving the XML Problem with Jackson - Stackify
The absolute simplest way of working with this is to just use the default configuration: ObjectMapper objectMapper = new XmlMapper();. However, ...
Read more >
How to use XmlFactory in com.fasterxml.jackson.dataformat.xml
module.setDefaultUseWrapper(defaultUseWrapper); return new XmlMapper(new XmlFactory(StaxUtils.createDefensiveInputFactory()), module);
Read more >
Bnd, ServiceLoader and javax.xml.stream.FactoryFinder
The only way I know to add extra requirements to Bnd is: ... XMLInputFactory)';osgi.serviceloader='javax.xml.stream.XMLInputFactory' ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found