Data::Dumper for java

Discussion in 'Java' started by horos11@gmail.com, Apr 6, 2009.

  1. Guest

    Perl has a very nice class called Data::Dumper which recursively
    prints out data structures and objects, such that if an object owns
    other objects, those too are printed out in 'standardized' form (ie:
    showing all public and private fields of those subobjects).

    Is there an equivalent module in java?

    I know you could make one using reflection; my question is *has*
    someone made one, one that is tunable (ie: that can override objects'
    toString() methods, shows only so many levels of output, etc. Being
    able to override toString() for subobjects is very important because
    Java so helpfully provides a somewhat meaningless toString() function
    for Object)

    Thanks much for any info,

    Ed
    , Apr 6, 2009
    #1
    1. Advertising

  2. Mark Space Guest

    wrote:
    > Perl has a very nice class called Data::Dumper which recursively
    > prints out data structures and objects, such that if an object owns
    > other objects, those too are printed out in 'standardized' form (ie:
    > showing all public and private fields of those subobjects).
    >
    > Is there an equivalent module in java?
    >
    > I know you could make one using reflection; my question is *has*
    > someone made one, one that is tunable (ie: that can override objects'
    > toString() methods, shows only so many levels of output, etc. Being
    > able to override toString() for subobjects is very important because
    > Java so helpfully provides a somewhat meaningless toString() function
    > for Object)



    I'm unfamiliar with Perl and it's libraries, so I have to ask -- what
    would you do with such a thing?

    For debugging, my debugger shows me all I need, with out any work
    whatsoever on my part. I haven't looked into logging utilities but the
    default ones do take an object as a parameter. This might just invoke
    toString() however. Then there's Serialization and XMLEncoder/Decoder,
    which might be consdiered "stadardized" forms also.

    For documentation, there's this thing called Javadoc. Try it, you might
    like it.
    Mark Space, Apr 6, 2009
    #2
    1. Advertising

  3. Stefan Ram Guest

    writes:
    >Is there an equivalent module in java?


    Partially, there is no need for ::Data::Dumper::Dumper, because
    Java already has the, er, message »toString()« for this purpose.

    But, »toString()« has difficulties. To get a meaningful dump,
    one does not use »array.toString()«, but
    »java.util.Arrays.toString( a )«.

    »toString()« also might not always dump all details.

    Objects can be dumped to XML using

    http://xstream.codehaus.org/

    .

    I have started to writte my own dumper, which still is
    experimental, incomplete work-in-progress with some known bugs
    and limitations:

    class User { public int id = 0; }

    public class Main
    { public static void main( final java.lang.String[] args )
    { User user = new User();
    java.lang.System.out.println
    ( new de.dclj.ram.notation.junobjects.Junobjects().dump( user )); }}

    < &objectmap
    object =
    < &User
    id =
    < &int 0 >>>

    The library is avaiable at

    http://www.purl.org/stefan_ram/pub/ram-jar

    >I know you could make one using reflection; my question is *has*
    >someone made one, one that is tunable (ie: that can override objects'
    >toString() methods, shows only so many levels of output, etc. Being
    >able to override toString() for subobjects is very important because
    >Java so helpfully provides a somewhat meaningless toString() function
    >for Object)


    Now I see, you already knew about »toString()«!

    Yes, my dumper uses reflection, but does not care about
    »toString()« implementations.

    However, your idea to use overriding to control the dumper
    is good!

    The source code of my dumper is available under the GPL as
    indicated on the web site.

    More examples:

    The next example shows a self reference:

    class Ship
    { Ship ship;
    final java.lang.String a0 = "abc";
    final java.lang.String a1 = "abc";
    final java.lang.String a2 = new java.lang.String( a1 ); }

    public class Main
    { public static void main( final java.lang.String[] args )
    { Ship ship = new Ship(); ship.ship = ship; // add self reference
    java.lang.System.out.println
    ( new de.dclj.ram.notation.junobjects.Junobjects().dump( ship )); }}

    outputs:

    < &objectmap
    object =
    < &Ship
    a0 =
    < &java.lang.String zz0 >
    a1 =
    < &java.lang.String zz0 >
    a2 =
    < &java.lang.String zz1 >
    ship =
    < &Ship object >>
    zz0 =
    < &java.lang.String
    count =
    < &int 3 >
    hash =
    < &int 0 >
    offset =
    < &int 0 >
    value =
    < &[char[]] a b c >>
    zz1 =
    < &java.lang.String
    count =
    < &int 3 >
    hash =
    < &int 0 >
    offset =
    < &int 0 >
    value =
    < &[char[]] a b c >>>

    public class Main
    { public static void main( final java.lang.String[] args )
    { final java.util.HashMap<java.lang.String,java.lang.Integer> hashMap
    = new java.util.HashMap<java.lang.String,java.lang.Integer>();
    hashMap.put( "a", 1 );
    hashMap.put( "b", 2 );
    java.lang.System.out.println
    ( new de.dclj.ram.notation.junobjects.Junobjects().dump( hashMap )); }}

    < &objectmap
    object =
    < &java.util.HashMap
    entrySet =
    < >
    loadFactor =
    < &float 0.75 >
    modCount =
    < &int 2 >
    size =
    < &int 2 >
    table =
    < &[java.util.HashMap.Entry[]]
    < null >
    < null >
    < null >
    < null >
    < &java.util.HashMap.Entry zz0 >
    < null >
    < null >
    < &java.util.HashMap.Entry zz1 >
    < null >
    < null >
    < null >
    < null >
    < null >
    < null >
    < null >
    < null >>
    threshold =
    < &int 12 >>
    zz0 =
    < &java.util.HashMap.Entry
    hash =
    < &int 100 >
    key =
    < &java.lang.String zz2 >
    next =
    < >
    value =
    < &java.lang.Integer zz3 >>
    zz1 =
    < &java.util.HashMap.Entry
    hash =
    < &int 103 >
    key =
    < &java.lang.String zz4 >
    next =
    < >
    value =
    < &java.lang.Integer zz5 >>
    zz2 =
    < &java.lang.String
    count =
    < &int 1 >
    hash =
    < &int 98 >
    offset =
    < &int 0 >
    value =
    < &[char[]] b >>
    zz3 =
    < &java.lang.Integer
    value =
    < &int 2 >>
    zz4 =
    < &java.lang.String
    count =
    < &int 1 >
    hash =
    < &int 97 >
    offset =
    < &int 0 >
    value =
    < &[char[]] a >>
    zz5 =
    < &java.lang.Integer
    value =
    < &int 1 >>>

    class A { final B b; final C c;
    public A( final B b, final C c ){ this.b = b; this.c = c; }}
    class B { final int m = 1; final java.lang.String x = "X";
    final D d;
    public B( final D d ){ this.d = d; }}
    class C { final int n = 2; final java.lang.String y = "Y";
    final D d;
    public C( final D d ){ this.d = d; }} class D {}

    public class Main
    { public static void main( final java.lang.String[] args )
    { final D d = new D();
    final B b = new B( d );
    final C c = new C( d );
    final A a = new A( b, c );
    java.lang.System.out.println
    ( new de.dclj.ram.notation.junobjects.Junobjects().dump( a )); }}

    < &objectmap
    object =
    < &A
    b =
    < &B zz0 >
    c =
    < &C zz1 >>
    zz0 =
    < &B
    d =
    < &D zz3 >
    m =
    < &int 1 >
    x =
    < &java.lang.String zz2 >>
    zz1 =
    < &C
    d =
    < &D zz3 >
    n =
    < &int 2 >
    y =
    < &java.lang.String zz4 >>
    zz2 =
    < &java.lang.String
    count =
    < &int 1 >
    hash =
    < &int 0 >
    offset =
    < &int 0 >
    value =
    < &[char[]] X >>
    zz3 =
    < &D >
    zz4 =
    < &java.lang.String
    count =
    < &int 1 >
    hash =
    < &int 0 >
    offset =
    < &int 0 >
    value =
    < &[char[]] Y >>>
    Stefan Ram, Apr 6, 2009
    #3
  4. Guest


    > I'm unfamiliar with Perl and it's libraries, so I have to ask -- what
    > would you do with such a thing?


    Avoid having to write toString() functions for all of your modules,
    sprinkle your code with printlns without needing to worry about
    implementation, get good defaults for printing out structures like
    List<String>..

    >
    > For debugging, my debugger shows me all I need, with out any work
    > whatsoever on my part.  I haven't looked into logging utilities but the
    > default ones do take an object as a parameter.  This might just invoke
    > toString() however.  Then there's Serialization and XMLEncoder/Decoder,
    > which might be consdiered "stadardized" forms also.


    yes, if you can get that ability inside of jdb, let me know. And I
    don't have access to x11 on the place where I need to run the code, so
    if you know how to run code on a server, serialize input and output
    via an ssh shell, and get the output into an intellij/eclipse IDE, I'd
    love to know that too. Use an IDE is great as long as you have access
    to an IDE.

    Ed
    , Apr 6, 2009
    #4
  5. Guest

    On Apr 6, 1:20 pm, -berlin.de (Stefan Ram) wrote:
    > writes:
    > >Is there an equivalent module in java?

    >
    >   Partially, there is no need for ::Data::Dumper::Dumper, because
    >   Java already has the, er, message »toString()« for this purpose.
    >
    >   But, »toString()« has difficulties. To get a meaningful dump,
    >   one does not use »array.toString()«, but
    >   »java.util.Arrays.toString( a )«.
    >


    Thanks.. I'll give it a try.

    Ed
    , Apr 6, 2009
    #5
  6. Guest

    On Apr 6, 1:46 pm, Patricia Shanahan <> wrote:
    > wrote:
    > >> I'm unfamiliar with Perl and it's libraries, so I have to ask -- what
    > >> would you do with such a thing?

    >
    > > Avoid having to write toString() functions for all of your modules,
    > > sprinkle your code with printlns without needing to worry about
    > > implementation, get good defaults for printing out structures like
    > > List<String>..

    >
    > ...
    >
    > This idea would be harder to implement usefully in Java than in many
    > other languages. The problem is pointer chasing without getting into
    > perpetual loops.
    >
    > Java has no concept of a structure containing another structure, only
    > having a pointer to it. If you do not follow pointers, all you get is
    > the values of primitive fields. If you do follow pointers, there is no
    > way to distinguish the ones that could lead to loops.
    >
    > This is not a problem for interactive display, because the user chooses
    > when to expand a pointer target.
    >
    > Patricia


    Of course, it would be relatively difficult, but perl has the ability
    to self-reference as well - and Data::Dumper works with it just fine.
    You need to keep a list of 'seen' pointers via address and recognize
    when they have been printed out or not.

    In any case, it looks like xstream is what I want (or close to it) -
    it has the additional benefit of being able to serialize objects in a
    readable xml format as well for transfer over a network. Stefan's
    Dumper class (above) looks interesting too..

    Ed
    , Apr 6, 2009
    #6
  7. Mark Space Guest

    wrote:

    > yes, if you can get that ability inside of jdb, let me know. And I
    > don't have access to x11 on the place where I need to run the code, so
    > if you know how to run code on a server, serialize input and output


    Ah, so. Debugging then. Yes, this is the worst possible situation to
    be in: debugging a problem without an adequate debugging harness.

    Consider copying the code locally and reproducing the problem locally so
    that you can attach a debugger.

    Or bite the bullet and install whatever you need to debug on the server,
    and attach to that. It's just a network connection.

    Just curious: is your boss paying you by the hour for this? Or did you
    get roped into it on a contract?
    Mark Space, Apr 6, 2009
    #7
  8. Mark Rafn Guest

    Patricia Shanahan <> wrote:
    >This idea would be harder to implement usefully in Java than in many
    >other languages. The problem is pointer chasing without getting into
    >perpetual loops.


    That's no harder in Java than anywhere else. You need to handle multiple
    references to the same object, which you can check with == rather than
    ..equals. IdentityHashSet is an easy way to do so. In fact, Perl does support
    arbitrary reference graphs, and Data::Dumper handles it.

    It's not as compact a format as Perl's Data::Dumper, and it takes more work
    than just an eval to reconstitute, but java.beans.XMLEncoder is pretty close
    to what you're looking for. A version that is perl-compatible (especially
    read and write compatible) would actually be a pretty cool thing.
    --
    Mark Rafn <http://www.dagon.net/>
    Mark Rafn, Apr 6, 2009
    #8
  9. Stefan Ram Guest

    -berlin.de (Stefan Ram) writes:
    > ( new de.dclj.ram.notation.junobjects.Junobjects().dump( ship )); }}


    I have been informed that the source code from my Zip file
    cannot be compiled to create the JAR. Sorry. Here is a Fix:

    To create the JAR from the ZIP:

    - download and extract the ZIP file, then extract the inner ZIP file.

    - now rename 11 offending Java files, so that the compiler will not
    try to compile them:

    In de\dclj\ram\notation\bauer\prescanner rename:
    Cursor.java -> Cursor.txt
    Pretoken.java -> Pretoken.txt
    PretokenListBuilder.java -> PretokenListBuilder.txt
    Autotoken.java -> Autotoken.txt

    In de\dclj\ram\notation\bauer\scanner rename:
    Token.java -> Token.txt

    In de\dclj\ram\notation\bauer\parser rename:
    OperatorToken.java -> OperatorToken.txt
    OperatorStack.java -> OperatorStack.txt

    In de\dclj\ram\system\iteration rename:
    TupleNesting.java -> TupleNesting.txt
    IntegralRange.java -> IntegralRange.txt

    In de\dclj\ram\javax\swing rename:
    GenericMenuItem.java -> GenericMenuItem.txt

    In de\dclj\ram\application\club rename:
    Main.java -> Main.txt

    - Then the library can be built and used with
    a »Main.java« from the above post:

    cd src
    find . -name *.java -print >sources.txt
    javac -d ../lib -source 1.6 -target 1.6 -encoding UTF-8 @sources.txt
    cd ..
    cd lib
    find . -name *.class -print >classes.txt
    jar cf ram.jar @classes.txt
    javac -classpath .;ram.jar Main.java
    java -cp .;ram.jar Main
    Stefan Ram, Apr 7, 2009
    #9
  10. Guest

    well, re-implementing the world isn't really feasible, since there are
    network rules about which machines attach to which, and that rules out
    connections as well (everything is 3rd party hosted)..

    But in any case, there are benefits of having a dumper object
    regardless of the API you use, IMO. If the Serialization order is
    reproducable (ie: the same objects always go to the same
    representations) then you can do a visual diff against two objects and
    get a concise idea of changes.

    Or, you can store (in dev and test anyways) representations of objects
    as they happen by external testing - ie: you can see at a glance what
    data problems might cause a given bug to happen.

    And of course, if the Serialization is both human and java writable
    and human and java readable, you can use it to develop unit tests for
    your application, sometimes many unit tests from one source.

    So.. many uses, I would say.

    Ed


    On Apr 6, 1:59 pm, Mark Space <> wrote:
    > wrote:
    > > yes, if you can get that ability inside of jdb, let me know. And I
    > > don't have access to x11 on the place where I need to run the code, so
    > > if you know how to run code on a server, serialize input and output

    >
    > Ah, so.  Debugging then.  Yes, this is the worst possible situation to
    > be in: debugging a problem without an adequate debugging harness.
    >
    > Consider copying the code locally and reproducing the problem locally so
    > that you can attach a debugger.
    >
    > Or bite the bullet and install whatever you need to debug on the server,
    > and attach to that.  It's just a network connection.
    >
    > Just curious: is your boss paying you by the hour for this?  Or did you
    > get roped into it on a contract?
    , Apr 7, 2009
    #10
  11. Mark Space Guest

    wrote:
    > well, re-implementing the world isn't really feasible, since there are
    > network rules about which machines attach to which, and that rules out
    > connections as well (everything is 3rd party hosted)..



    Re-implementing the world shouldn't be needed. The first step would be
    to try re-create the problem locally as simply as possible. If you
    can't recreate the problem, only then do you have to expend your test
    harness to cover more cases.

    Some kind of generic network blaster would be a start. (If anyone know
    of a good network blaster for HTTP, let me know, I'm still looking.) If
    you have something besides HTTP, then whatever kind of "random data" you
    can cook up would be the first place to start. Often, random data will
    shake a lot of bugs out of a system.

    The other thing you can do is just record input, and replay it locally
    to reproduce the problem. Most operating systems have a low-level
    packet recorder of some type built in. If you were smart, you built one
    into your own system too. In a pinch, many network sniffers (separate
    box you plug into your network) will do the same thing.
    Mark Space, Apr 7, 2009
    #11
  12. Guest

    On Apr 6, 9:35 pm, wrote:
    >
    > yes, if you can get that ability inside of jdb, let me know. And I
    > don't have access to x11 on the place where I need to run the code, so
    > if you know how to run code on a server, serialize input and output
    > via an ssh shell, and get the output into an intellij/eclipse IDE, I'd
    > love to know that too. Use an IDE is great as long as you have access
    > to an IDE.


    Unless I'm mistaken remote debugging and remote profiling in Java
    can easily be done from your IDE / Debugger / Profiler. You can
    connect to a remote headless server.

    For remote profiling it's trivial, I do it regularly.

    This is really one of these area where Java shines
    compared to other languages. It's not that "Java the
    language" is that great (it's OK but it has a few
    warts) but the APIs and 3rd party APIs are great and,
    most notably, "Java the virtual machine" is a wonderful
    piece of engineering.

    Google for JVMTI (since 1.5 AFAIR):

    http://java.sun.com/javase/6/docs/technotes/guides/jvmti/

    Note that I'm not saying there's no use for what your
    asking: what you're asking still looks like a good idea.

    But to do "remote debugging on a headless server", there's
    really no need to "run the code on a server,
    serialize IO via an ssh shell, and get the output
    in an intellij/eclipse IDE" [sic].

    That's the kind of hackery needed with other, less
    well-tought, technologies.

    You're talking about SSH so if security is an issue you
    can always tunnel the port(s) used for remote debugging/
    profiling using SSH.

    Charles.
    , Apr 7, 2009
    #12
  13. Mark Rafn wrote:
    > Patricia Shanahan <> wrote:
    >> This idea would be harder to implement usefully in Java than in many
    >> other languages. The problem is pointer chasing without getting into
    >> perpetual loops.

    >
    > That's no harder in Java than anywhere else. You need to handle multiple
    > references to the same object, which you can check with == rather than
    > .equals. IdentityHashSet is an easy way to do so. In fact, Perl does support
    > arbitrary reference graphs, and Data::Dumper handles it.
    >
    > It's not as compact a format as Perl's Data::Dumper, and it takes more work
    > than just an eval to reconstitute, but java.beans.XMLEncoder is pretty close
    > to what you're looking for. A version that is perl-compatible (especially
    > read and write compatible) would actually be a pretty cool thing.


    Data::Dumper is effectively a serializer/deserializer for complex
    compound objects. Its just that the deserializer is part of the language
    and not a separate module.

    This is similar to JSON isn't it? Maybe a Java JSON serializer would
    meet the OPs needs? Google found flexjson, jsontools etc.

    <off_topic>
    Since I'm currently grappling with the labyrinthine baroque mess that is
    WS-I/WSSE/WSDL/XSD/JAX-WS, I have to say that I wish JSON was more
    popular with large consulting companies than SOAP and it's monstrous
    friends.
    </off_topic>

    --
    RGB
    RedGrittyBrick, Apr 7, 2009
    #13
  14. Guest

    > Data::Dumper is effectively a serializer/deserializer for complex
    > compound objects. Its just that the deserializer is part of the language
    > and not a separate module.


    just a quick correction - Data::Dumper is provided with the perl core,
    but it is not part of the language itself..

    > This is similar to JSON isn't it? Maybe a Java JSON serializer would
    > meet the OPs needs? Google found flexjson, jsontools etc.


    yes, that works, but it won't do full serialization (ie: the
    conversion is lossy.
    In any case, xstream has a JSON module as well as an XML one, and it
    works great for large datastructures. I've been using it for debugging
    and am pretty happy so far.

    Ed
    , Apr 7, 2009
    #14
  15. Tom Anderson Guest

    On Mon, 6 Apr 2009, wrote:

    > Is there an equivalent module in java?


    You've solved this, but my suggestion would have been to serialize objects
    on the remote machine using normal serialization, then resurrect them on a
    dev machine where you can inspect them with a debugger. The resurrection
    code is trivial - four lines, then something to breakpoint on. Of course,
    this only works if your objects are serializable!

    tom

    --
    You have now found yourself trapped in an incomprehensible maze.
    Tom Anderson, Apr 7, 2009
    #15
  16. Arne Vajhøj Guest

    RedGrittyBrick wrote:
    > <off_topic>
    > Since I'm currently grappling with the labyrinthine baroque mess that is
    > WS-I/WSSE/WSDL/XSD/JAX-WS, I have to say that I wish JSON was more
    > popular with large consulting companies than SOAP and it's monstrous
    > friends.
    > </off_topic>


    They solve rather different problems.

    The best you could hope for would be REST and schemas.

    Arne
    Arne Vajhøj, Apr 8, 2009
    #16
  17. Roedy Green Guest

    On Mon, 6 Apr 2009 11:37:26 -0700 (PDT), wrote,
    quoted or indirectly quoted someone who said :

    >Perl has a very nice class called Data::Dumper which recursively
    >prints out data structures and objects, such that if an object owns
    >other objects, those too are printed out in 'standardized' form (ie:
    >showing all public and private fields of those subobjects).


    To implement such a beast, you might look at
    http://mindprod.com/jgloss/reflection.html

    The closest thing I can think of is implementing a dump or toString
    method is all my classes for dumping out the object's data in debug
    suitable format. Each class then decides how must detail about
    subbjects to display.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    "At this point, 29 percent of fish and seafood species have collapsed - that is,
    their catch has declined by 90 percent. It is a very clear trend, and it is accelerating.
    If the long-term trend continues, all fish and seafood species are projected to collapse
    within my lifetime -- by 2048."
    ~ Dr. Boris Worm of Dalhousie University
    Roedy Green, Apr 8, 2009
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kamal
    Replies:
    0
    Views:
    983
    kamal
    Aug 12, 2003
  2. Eric
    Replies:
    0
    Views:
    4,410
  3. rc
    Replies:
    3
    Views:
    1,876
    Chris Uppal
    Aug 16, 2004
  4. Sam

    Data::Dumper for Java?

    Sam, Nov 30, 2004, in forum: Java
    Replies:
    4
    Views:
    7,665
    Anonymous
    Feb 11, 2011
  5. Replies:
    4
    Views:
    248
    Paul Lalli
    Aug 1, 2007
Loading...

Share This Page