Data::Dumper for java

H

horos11

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
 
M

Mark Space

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.
 
S

Stefan Ram

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 >>>
 
E

ed.peschko

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 said:
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
 
E

ed.peschko

  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
 
H

horos11

...

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
 
M

Mark Space

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?
 
M

Mark Rafn

Patricia Shanahan said:
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.
 
S

Stefan Ram

( 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
 
H

horos11

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
 
M

Mark Space

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.
 
C

cbossens73

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.
 
R

RedGrittyBrick

Mark said:
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>
 
H

horos11

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
 
T

Tom Anderson

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
 
A

Arne Vajhøj

RedGrittyBrick said:
<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
 
R

Roedy Green

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top