Giter VIP home page Giter VIP logo

pojomatic's Introduction

Pojomatic

Pojomatic provides configurable implementations of the equals(Object), hashCode() and toString() methods inherited from java.lang.Object.

For example, the following bean has been "pojomated":

import org.pojomatic.Pojomatic;
import org.pojomatic.annotations.AutoProperty;

@AutoProperty
public class Person {
  private final String firstName;
  private final String lastName;
  private final int age;

  public Person(String firstName, String lastName, int age) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }

  public String getFirstName() { return this.firstName; }
  public String getLastName() { return this.lastName; }
  public int getAge() { return this.age; }

  @Override public boolean equals(Object o) {
    return Pojomatic.equals(this, o);
  }

  @Override public int hashCode() {
    return Pojomatic.hashCode(this);
  }

  @Override public String toString() {
    return Pojomatic.toString(this);
  }
}

The above class implements equals and hashCode methods following the best practices outlined in Josh Bloch's Efective Java. Moreover, running

System.out.println(new Person("John", "Doe", 32).toString());

will result in the following output:

Person{firstName: {John}, lastName: {Doe}, age: {32}}

For more information and examples, see the Pojomatic site

pojomatic's People

Contributors

hansenc avatar irobertson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pojomatic's Issues

java.lang.UnsupportedOperationException: This feature requires ASM7

pojomatic-2.1.0
openjdk version "11.0.1" 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

With asm-6.2.1:
Caused by: java.lang.UnsupportedOperationException
at org.objectweb.asm.ClassVisitor.visitNestHostExperimental(ClassVisitor.java:158)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:541)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
at org.pojomatic.internal.PropertyClassVisitor.visitClass(PropertyClassVisitor.java:46)
at org.pojomatic.internal.ClassProperties.extractClassProperties(ClassProperties.java:183)
at org.pojomatic.internal.ClassProperties.walkHierarchy(ClassProperties.java:161)
at org.pojomatic.internal.ClassProperties.(ClassProperties.java:81)
at org.pojomatic.internal.ClassProperties.(ClassProperties.java:26)
at org.pojomatic.internal.ClassProperties$1.create(ClassProperties.java:39)
at org.pojomatic.internal.ClassProperties$1.create(ClassProperties.java:36)
at org.pojomatic.internal.SelfPopulatingMap.tryCreatingValue(SelfPopulatingMap.java:46)
at org.pojomatic.internal.SelfPopulatingMap.get(SelfPopulatingMap.java:22)
at org.pojomatic.internal.ClassProperties.forClass(ClassProperties.java:64)
at org.pojomatic.internal.PojomatorFactory.makePojomatorChecked(PojomatorFactory.java:33)
at org.pojomatic.internal.PojomatorFactory.access$000(PojomatorFactory.java:16)
at org.pojomatic.internal.PojomatorFactory$1.run(PojomatorFactory.java:22)
at org.pojomatic.internal.PojomatorFactory$1.run(PojomatorFactory.java:19)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.pojomatic.internal.PojomatorFactory.makePojomator(PojomatorFactory.java:19)
at org.pojomatic.Pojomatic$1.create(Pojomatic.java:77)
at org.pojomatic.Pojomatic$1.create(Pojomatic.java:72)
at org.pojomatic.internal.SelfPopulatingMap.tryCreatingValue(SelfPopulatingMap.java:46)
at org.pojomatic.internal.SelfPopulatingMap.get(SelfPopulatingMap.java:22)
at org.pojomatic.Pojomatic.pojomator(Pojomatic.java:178)
at org.pojomatic.Pojomatic.toString(Pojomatic.java:93)

With asm-7.0:
Caused by: java.lang.UnsupportedOperationException: This feature requires ASM7
at org.objectweb.asm.ClassVisitor.visitNestHost(ClassVisitor.java:150)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:541)
at org.objectweb.asm.ClassReader.accept(ClassReader.java:391)
at org.pojomatic.internal.PropertyClassVisitor.visitClass(PropertyClassVisitor.java:46)
at org.pojomatic.internal.ClassProperties.extractClassProperties(ClassProperties.java:183)
at org.pojomatic.internal.ClassProperties.walkHierarchy(ClassProperties.java:161)
at org.pojomatic.internal.ClassProperties.(ClassProperties.java:81)
at org.pojomatic.internal.ClassProperties.(ClassProperties.java:26)
at org.pojomatic.internal.ClassProperties$1.create(ClassProperties.java:39)
at org.pojomatic.internal.ClassProperties$1.create(ClassProperties.java:36)
at org.pojomatic.internal.SelfPopulatingMap.tryCreatingValue(SelfPopulatingMap.java:46)
at org.pojomatic.internal.SelfPopulatingMap.get(SelfPopulatingMap.java:22)
at org.pojomatic.internal.ClassProperties.forClass(ClassProperties.java:64)
at org.pojomatic.internal.PojomatorFactory.makePojomatorChecked(PojomatorFactory.java:33)
at org.pojomatic.internal.PojomatorFactory.access$000(PojomatorFactory.java:16)
at org.pojomatic.internal.PojomatorFactory$1.run(PojomatorFactory.java:22)
at org.pojomatic.internal.PojomatorFactory$1.run(PojomatorFactory.java:19)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at org.pojomatic.internal.PojomatorFactory.makePojomator(PojomatorFactory.java:19)
at org.pojomatic.Pojomatic$1.create(Pojomatic.java:77)
at org.pojomatic.Pojomatic$1.create(Pojomatic.java:72)
at org.pojomatic.internal.SelfPopulatingMap.tryCreatingValue(SelfPopulatingMap.java:46)
at org.pojomatic.internal.SelfPopulatingMap.get(SelfPopulatingMap.java:22)
at org.pojomatic.Pojomatic.pojomator(Pojomatic.java:178)
at org.pojomatic.Pojomatic.toString(Pojomatic.java:93)

Failing code example pojomatic_bug_14.tar.gz

Getting Invalid Byte Tag in Constant Pool when loading pojomatic on Tomcat 8

I know that Pojomatic is supposed to support Java 1.7 and above.

The error I'm getting is this at context load time:

2019-04-03 14:02:27,618 [omsdp140b2-startStop-1] ERROR org.apache.catalina.startup.ContextConfig- Unable to process Jar entry [module-info.class] from Jar [file:/WEB-INF/lib/pojomatic-2.2.1.jar] for annotations
org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 19
  at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:97) ~[tomcat-coyote.jar:8.5.5]
  at org.apache.tomcat.util.bcel.classfile.ConstantPool.<init>(ConstantPool.java:54) ~[tomcat-coyote.jar:8.5.5]
  at org.apache.tomcat.util.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:174) ~[tomcat-coyote.jar:8.5.5]
<there's more here, but it's not relevant>

Some googling leads me to this, which suggests this can happen if the underlying library was compiled using a Java 9+ compiler (I think this might even come into play if the source and target are set to 1.7, since at least the library changes stay).

https://documentation.magnolia-cms.com/display/DOCS57/_known+issue+with+tomcat+8.5x+JAVA+EE+and+BCEL

I'm working on getting the version of tomcat used upgraded, but it might be helpful to know which are compiled with java 9+.

Is version 2.2.0 compiled with a pre-9 version of java? The error seems to go away if I use that.

POJOMATORS a potential memory leak

Pojomatic statically caches the handler for each Class. This could produce a memory leak in case you run it on a Class in a ClassLoader which is later thrown away.

Using WeakHashMap unfortunately does not help, since values refer to keys, and apparently there is no perfect solution. See my JDK-6389107; probably the best you can do is to hold the value with a SoftReference.

Add module support to pojomatic

At minimum, this would mean adding an entry to manifest.mf, but we should be able to go the distance and add a proper module-info file.

Under Java7, property order is indeterminant

As of Java7, the order of fields and methods returned by reflection, which was never guaranteed to be in any particular order, is now indeed not (in general) in source-code order. This breaks two tests in PojomatorImplTest (testShortCircuitEquals and testToStringNames), and can cause similar issues in real-world code.

Propsed fix - use ASM to parse the classfile to get the order from there.

Option to compare Comparable property values using compareTo() instead of equals()

While testing some database persistence, I've found that what I write out to the datastore and what gets read back from it is not always in the same format.

Example: write out price as a BigDecimal("0"), but when read back in I get BigDecimal("0.00"). Or writing out a java.util.Date, and the persistence layer reads it in as a java.sql.Timestamp.

Though the values they represent are effectively equivalent, BigDecimal.equals() returns false if the values have different scales. Timestamp.equals(Date) will always return false, but Date.equals(Timestamp) will return true if the represented time is the same.

Can we get a feature to control how property values are compared for equality?

Proposal: introduce a new property to @Property annotation:

@interface Property {
...
PropertyEquivalence equivalenceMethod default PropertyEquivalence.EQUALS;
}

enum PropertyEquivalence { EQUALS, COMPARE_TO; }

When equivalence method is COMPARE_TO, then the Pojomator should sanity check that 1) the property policy does not include hash coding, and 2) the property type is Comparable,

In the meantime, I will keep calling BigDecimal.setScale, and converting Dates to Timestamps in setters. :(

Pojomatic failing on Java 7 and 8

Attempting to run pojomatic version 2.1.0 or 2.2.0 under java 7 or 8 results in an UnsupportedClassVersionError from ClassDefinerFactory.makeDefiner

Under Java8 ASM classreader fails

java.lang.IllegalArgumentException
at org.kohsuke.asm4.ClassReader.(ClassReader.java:167)
at org.kohsuke.asm4.ClassReader.(ClassReader.java:153)
at org.kohsuke.asm4.ClassReader.(ClassReader.java:458)
at org.pojomatic.internal.PropertyClassVisitor.visitClass(PropertyClassVisitor.java:44)
at org.pojomatic.internal.ClassProperties.extractClassProperties(ClassProperties.java:183)
at org.pojomatic.internal.ClassProperties.walkHierarchy(ClassProperties.java:161)
at org.pojomatic.internal.ClassProperties.(ClassProperties.java:81)
at org.pojomatic.internal.ClassProperties.(ClassProperties.java:26)
at org.pojomatic.internal.ClassProperties$1.create(ClassProperties.java:39)
at org.pojomatic.internal.ClassProperties$1.create(ClassProperties.java:36)
at org.pojomatic.internal.SelfPopulatingMap.tryCreatingValue(SelfPopulatingMap.java:44)
at org.pojomatic.internal.SelfPopulatingMap.get(SelfPopulatingMap.java:20)
at org.pojomatic.internal.ClassProperties.forClass(ClassProperties.java:64)
at org.pojomatic.internal.PojomatorFactory.makePojomatorChecked(PojomatorFactory.java:67)
at org.pojomatic.internal.PojomatorFactory.access$100(PojomatorFactory.java:17)
at org.pojomatic.internal.PojomatorFactory$2.run(PojomatorFactory.java:56)
at org.pojomatic.internal.PojomatorFactory$2.run(PojomatorFactory.java:53)
at java.security.AccessController.doPrivileged(Native Method)
at org.pojomatic.internal.PojomatorFactory.makePojomator(PojomatorFactory.java:53)
at org.pojomatic.Pojomatic$1.create(Pojomatic.java:80)
at org.pojomatic.Pojomatic$1.create(Pojomatic.java:75)
at org.pojomatic.internal.SelfPopulatingMap.tryCreatingValue(SelfPopulatingMap.java:44)
at org.pojomatic.internal.SelfPopulatingMap.get(SelfPopulatingMap.java:20)
at org.pojomatic.Pojomatic.pojomator(Pojomatic.java:181)
at org.pojomatic.Pojomatic.hashCode(Pojomatic.java:109)
at com.etothea.directedgraph.MyVertex.hashCode(MyVertex.java:40)
at java.util.HashMap.hash(HashMap.java:338)
at java.util.HashMap.put(HashMap.java:611)
at java.util.HashSet.add(HashSet.java:219)
at java.util.AbstractCollection.addAll(AbstractCollection.java:344)

Unable to use Pojomatic with Java 9

ASM 5.x doesn't support Java 9 (cause IllegalArgumentException). Need to use ASM 6.0 :

<dependency>
  <groupId>org.ow2.asm</groupId>
  <artifactId>asm</artifactId>
  <version>6.0</version>
</dependency>

copyright info

Hi @irobertson, we use this library and in order to have this included in our OSL, we require copyright information. In the source code, I do not see the license or notice file included. Could you please provide that information here for dependency:

org.pojomatic
pojomatic
2.2.1

Allow to ignore fields/methods

It would be great to be able to decorate a class/field/methods, so that Pojomatic would not include some fields/methods into the comparison.
In my scenario, in a test I check data retrieved from a service against expected data (taken from static files) and there are a set of fields which I want to ignore, as they are updated on each call/creation (eg. id, lastChanged etc.)

Assume @AutoProperty when no annotations are found.

Currently, if a class attempts to use pojomatic, does not have any Pojomatic annotations, pojomatic will throw an exception.

It has been my experience that by far the most common way to deal with this has been to place an @AutoProperty annotation on the class. This ends up being boilerplate, and often is initially forgotten.

I would like to propose that when pojomatic finds no pojomatic annotations on a class or any of its superclasses, that it assume the presence of @AutoProperty on each class in the inheritance hierarchy.

Strictly speaking, this would be an incompatible change, but only in the sense that pojomatic would actually do something useful where it currently throws an exception. https://xkcd.com/1172/ not withstanding, this is a cost I'm willing to accept.

PojomaticAssert.assertEqualsWithDiff should identify nested

(Reported initially on the old google-code site by qualidafial, aka Matt Hall)

class Foo { @Property Bar bar; }
class Bar { @Property String baz; }

Foo expected = new Foo().withBar( new Bar().withBaz("abc") );
Foo actual = new Foo().withBar( new Bar().withBaz("123") );

In the above case, calling PojomaticAssert.assertEqualsWithDiff produces a message to the effect that Foo.bar is different for each object.

java.lang.AssertionError: differences between expected and actual:
bar: {Bar{baz: {"abc"}} versus
{Bar{baz: {"123"}}
(expected:
but was:)

Most of the time the differences can be sorted out by looking at toString().

However tonight I was bitten Hibernate's PersistentBag implementation, which uses instance equals despite the List interface contract. Thus the differences between my two instances was not evident from the toString() of expected and actual--they were both empty lists.

I propose enhancing Pojomatic.diff so that the description of any property difference will recurse on Pojomatic.diff, provided both property values are equals-compatible, and from pojomated classes.

I believe this change will help cut to the chase when debugging equals-related testing problems.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.