How Can I Add The OutputStream Using Programmatical Configuration in Log4j2? - configuration

Any idea how I can add my output stream to the build config?
ConfigurationBuilder<BuiltConfiguration> builder =
ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder osAppender = builder.newAppender("os", "OutputStream");
osAppender.addAttribute("target", myStream);
builder.add(osAppender);
BuiltConfiguration config = builder.build();
Configurator.initialize(config);
This is the Error message I get:
2022-01-27 15:04:41,203 main ERROR OutputStream contains an invalid element or attribute "target"
2022-01-27 15:04:41,227 main ERROR Could not create plugin of type class org.apache.logging.log4j.core.appender.OutputStreamAppender for element OutputStream: java.lang.NullPointerException java.lang.NullPointerException
at org.apache.logging.log4j.core.appender.OutputStreamAppender.getManager(OutputStreamAppender.java:159)
Thanks

The ConfigurationBuilder API does not allow you to set attributes which can not be serialized to a String. Therefore you'll need to use OutputSreamAppender's builder directly:
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
final Appender appender = OutputStreamAppender.newBuilder()//
.setTarget(myStream)
.setConfiguration(ctx.getConfiguration())
.build();
config.addLoggerAppender(ctx.getRootLogger(), appender);
See this question for another example of ConfigurationBuilder API vs direct instantiation of Log4j components.
Check also Log4j's architecture, which explains how all these components work together.

Related

XML to JSON in Camel Routing not working

I am trying to convert the XML message to JSON using camel router and save it into a file. Getting the XML message from the source and saving it to destination file etc are working. But when I try to convert to JSON, it did not work. I did not even throw any error/exception in logs. I am running on OSGI container
public class CamelRouter extends RouteBuilder {
#Override
public void configure() throws Exception {
from("file://C:/test/Sample.xml")
.routeId("file-to-file")
.log(LoggingLevel.INFO,"RouteID file-to-file !!!!! starting")
//From XML to JSON
.bean(CamelRouter.class, "convertXmlToJson")
.log(LoggingLevel.INFO,"From XML to JSON !!!!! Done")
.to("file://C:/test/JSONMessages")
.log(LoggingLevel.INFO,"Converted Message Saved successfully");
The bean method to convert XML to JSON convertXmlToJson is shown below
public String convertXmlToJson(String msg) {
log.info("NOW calling JSON conversion");
String jsonStr = null;
log.info("MESSAGE conversion starting : "); //After this message nothing happened
XMLSerializer xmlReader = new XMLSerializer();
log.info("MESSAGE before conversion : " + msg);
jsonStr = xmlReader.read(msg).toString();
log.info("JSON data : " + jsonObj.toString());
return jsonObj.toString();
}
Is anyone know why it is not executing the XMLSerializer portion. I tried this approach because the camel-xmljson's marshal().xmljson() call also give me the same results. Nothing happened after the xmljson() call in my camel routing.
Things that I checked are:
camel-xmljson feature up and running in OSGI
Dependencies mentioned in the Apache XmlJSON website added in my pom file, xom, camel-xmljson etc.
Am I missing anything here? Please help
The problem with your code route is that your bean component handler method resides within your route builder class, plus you invoke the bean component in a way that triggers another instantiation of that route builder class.
Personally, I would move convertXmlToJson to an appropriate utility class. That way you reduce mix of concern in the route builder and the bean component should work fine.
Alternatively, your route might work, if you invoke the bean component like this:
.bean(this, "convertXmlToJson")

javax.xml.bind.UnmarshalException when request rest json service with jersey client

I have a rest webservice (with jersey) which returns json list, if i call it directly it returns exactly this :
[{"success":false,"uri":"foo:22","message":"Unknown host : foo"},{"success":true,"uri":"localhost:8082","message":null}]
generated by this snippet :
#GET
#Path("/opening/")
public List<OpeningResult> testOpenings(#QueryParam("uri") List<String> uris) {
LOG.debug("testOpenings request uris :[" + uris + "]");
List<OpeningResult> openingResults = infoService.testOpenings(uris);
return openingResults;
}
It's a Collection of Pojo which look like this :
#XmlRootElement(name = "OpeningResult")
public class OpeningResult {
attributes
...
getter/setter
}
this Pojo is shared through a common jar between the server and the client.
i call the web service with this snippet :
Client client = Client.create();
WebResource resource = client.resource("http://localhost:8080/scheduler/rest/opening");
MultivaluedMap<String, String> params = new MultivaluedMapImpl();
for (String uri : uris) {
params.add("uri", uri);
}
List<OpeningResult> results = newArrayList(resource.queryParams(params).get(OpeningResult[].class));
I add some trace on the server side, i see that my rest service is called with the good parameters, buth on client side, i have this error :
Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"success"). Expected elements are <{}OpeningResult>
I don't find where it comes from ?
Modify your code to set up your client like this:
ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, true);
Client client = Client.create(clientConfig);
I had the exact same problem until this question and its answers pointed me in the right direction.
The situation is caused by the default jersey-json module used for serialization to and from JSON, which does not handle certain JSON constructs properly.
You can set the FEATURE_POJO_MAPPING flag to use the Jackson library's JacksonJsonProvider for JSON serialization instead.
Check out the Jersey Client side doc on using JSON. It looks like you're at least missing the annotation:
#Produces("application/json")
But you could also be missing the POJO Mapping feature filters for both client and server side. These all seem to be minor configuration changes.

JAXB Unmarshall exception - unexpected element

I have used a .xsd file to generate Java classes, and with an XML file, I need to unmarshall.
I am using this code :
JAXBContext objJAXBContext = JAXBContext.newInstance("my.test");
// create an Unmarshaller
Unmarshaller objUnmarshaller = objJAXBContext.createUnmarshaller();
FileInputStream fis = new FileInputStream("test.xml");
JAXBElement<Root> objMyRoot = (JAXBElement<Root>) objUnmarshaller.unmarshal(fis);
Root mRoot = objMyRoot.getValue();
and I am getting this error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Root"). Expected elements are (none)
I have seen many solutions but nothing works in my project.
What i can try to do?
Your xml root is missing the namespace (uri) attribute.
You better try this on the XMLRootElement ...
#XmlRootElement(name = "root", namespace="")
Try
StreamSource streamSource = new StreamSource("test.xml")
JAXBElement<Root> objMyRoot = (JAXBElement<Root>) objUnmarshaller.unmarshal(streamsource, Root.class);

jackson mini json to object class

I was added "jackson-mini-1.9.2.jar"(is not "jackson-all-1.9.2.jar") in my project,
I want to convert json to object class.
Use "jackson-all-1.9.2.jar",we can use "ObjectMapper" to get it.
but use "jackson-mini-1.9.2.jar",How to do it?
If I write the follow code"
String json = "{\"name\" : {\"first\" : \"Joe\", \"last\" : \"Sixpack\" }, \"gender\" : \"MALE\", \"verified\" : false, \"userImage\" : \"Rm9vYmFyIQ==\" }";
JsonFactory f = new JsonFactory();
JsonParser jp = f.createJsonParser(json);
User user = jp.readValueAs(User.class);
The result is like that:
Exception in thread "main" java.lang.IllegalStateException: No ObjectCodec defined for the parser, can not deserialize JSON into Java objects
at org.codehaus.jackson.JsonParser.readValueAs(Unknown Source)
at TestJackson.main(TestJackson.java:21)
You can implement your own ObjectCodec and then register it with the JsonFactory by calling JsonFactory#setCodec(myCodec).
Or (much easier!), just get hold of jackson-mapper-1.9.2.jar and add it to your classpath, so that you can use the default ObjectMapper.
If you want to use data-binding, do NOT use mini jar. It is only meant as the smallest possible jar to use Streaming Parsing (JsonParser, JsonGenerator).

Using DataContractJsonSerializer

I am trying to host a WCF service that responds to incoming requests by providing a json output stream. I have the following type
[DataContract]
[KnownType(typeof(List<HubCommon>))]
[KnownType(typeof(Music))]
[KnownType(typeof(AppsAndPlugins))]
[KnownType(typeof(Notifications))]
[KnownType(typeof(Scenes))]
[KnownType(typeof(Skins))]
[KnownType(typeof(Ringtones))]
[KnownType(typeof(Alarms))]
[KnownType(typeof(Widgets))]
[KnownType(typeof(Wallpapers))]
[KnownType(typeof(Soundsets))]
public class HubCommon{}
In my *.svc.cs file I do the following
List<HubCommon> hubContent = _ldapFacade.GetResults(query);
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(HubCommon));
serializer.WriteObject(stream,hubContent);
So essentially I am trying to serialize a List to Json but I get the following error on the "WriteObject" execution:-
The server encountered an error processing the request. The exception message is 'Type 'System.Collections.Generic.List`1[[HubContentCore.Domain.HubCommon, HubContentCore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' with data contract name 'ArrayOfHubCommon:http://schemas.datacontract.org/2004/07/HubContentCore.Domain' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'
What am I missing here ?
Thanks in advance.
The type of your DataContractJsonSerializer is HubCommon but you are writing an object of type List<HubCommon> and HubCommon is not added to the KnownTypAttribute