yegor256
yegor256

Reputation: 105083

How to log internals of an arbitrary object in Java?

I have a Java object with some unknown structure. Now I want to output this structure (properties and their values) to log file. And of course I'm interested to do this in recursive mode. Are there any libraries that can help me?

Upvotes: 6

Views: 356

Answers (8)

Oleg Majewski
Oleg Majewski

Reputation: 1019

A json serializer will do the job, e.g. using Gson:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;

...

private static final Logger LOG = LoggerFactory.getLogger(Your.class); 

...

Object obj = ...;
LOG.info(new Gson().toJson(obj));

Upvotes: 0

Ryan Stewart
Ryan Stewart

Reputation: 128829

XStream is extremely good at printing object graphs, even handling cycles without any extra configuration or extra code in your classes (i.e. no messing with toString()'s). Just add the library and you can do this to anything and get nice, useful output:

log.debug("The object: {}", new XStream().toXML(anyObject));

That will give you XML output. If you prefer JSON, you can get it with a tiny bit more work as detailed in the XStream JSON tutorial.

Upvotes: 6

Matt Wonlaw
Matt Wonlaw

Reputation: 12443

The java reflection API will give you access to all of this stuff (private members and all). To get private members, you will need to get yourObject.getClass().getDeclaredFields() to access a private field, remember to call yourField.setAccesible(true) on it.

Of course, you are very quickly going to run into problems by handrolling your own class to do this via reflection. The main problems come in when trying to decide to finally print a value and determining if it is an enum, a primitive, a primitive array and so on. You can use the Class.isPrimitive method to help figure that step out. To access elements of an array, use the java.lang.reflect.Array class.

The best option, which was posted earlier, is to use the ReflectionToStringBuilder of apache commons.

Upvotes: 0

JustinKSU
JustinKSU

Reputation: 4989

I have found the Apache Commons ToStringBuilder.reflectionToString() very useful. To get recursion you can override each Object's toString() method with a call to this function passing this.

http://commons.apache.org/lang/api-2.6/org/apache/commons/lang/builder/ToStringBuilder.html

Upvotes: 0

Aleks G
Aleks G

Reputation: 57316

You should use reflection. Have a look at java.lang.Class class, specifically .getFields() method.

Upvotes: 0

ratchet freak
ratchet freak

Reputation: 48196

you could use reflection

getClass and then go over each instance variable and go on (some objects can be handled specifically (like Strings))

Upvotes: 0

Olaf
Olaf

Reputation: 6289

I suggest you look either at Apache Commons BeanUtils or Apache Commons Lang, specifically ReflectionToStringBuilder.

Upvotes: 5

Jack Edmonds
Jack Edmonds

Reputation: 33171

Java serialization, which comes with Java, should do the trick. It will be in binary format though.

There is also XML serialization which can be provided by JAXB

Upvotes: 0

Related Questions