• Stars
    star
    256
  • Rank 153,423 (Top 4 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 13 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Library for introspecting generic type information of types, member/static methods, fields. Especially useful for POJO/Bean introspection.

Overview

ClassMate is a zero-dependency Java library for accurately introspecting type information, including reliable resolution of generic type declarations for both classes ("types") and members (fields, methods and constructors).

Project is licensed under Apache 2.

Status

Maven Central Javadoc Tidelift

Support

Community support

Classmate is supported by the community via the mailing list: java-classmate-user

Enterprise support

Available as part of the Tidelift Subscription.

The maintainers of classmate and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.

Contributing

Contributions are welcome (of course!); we require a simple one-page CLA to help simplify distribution (corporate users want to know how contributions are handled), one per contributor. Feel free to submit Pull Requests and we will get you through this formality.

One special case is that for reporting possible security issues ("vulnerabilities"), we recommend filing a Tidelift security contact (NOTE: you do NOT have to be a subscriber to do this).

Documentation

Project wiki has Javadocs.

External links that may help include:


Usage

Maven dependency

To use ClassMate via Maven, include following dependency:

<dependency>
  <groupId>com.fasterxml</groupId>
  <artifactId>classmate</artifactId>
  <version>1.5.1</version>
</dependency>

Java 9 module

Module name to use for Java 9 and above is com.fasterxml.classmate; module-info included from version 1.5.0 on.

Non-Maven

Downloads available from Project wiki.

Resolving Class type information

Main class used for fully resolving type information for classes is com.fasterxml.classmate.TypeResolver. TypeResolver does simple caching for resolved supertypes (since many subtypes resolve to smaller set of supertypes, typically). Since all access to shared data is synchronized, a single TypeResolver instance is typically shared for a single system (as a plain old static singleton): there are no benefits to instantiating more instances.

Its main resolution methods are:

  • resolve(Class cls): given a plain old class, will use generic type information that super type declarations (extends, implements) may have.
  • resolve(GenericType<T>): given a subtype of GenericType (which uses "Super-type Token" pattern), fully resolve type information
  • resolve(Class<?> baseType, Class<?> typeParameter1, ... , Class<?> typeParameter2): given base type (like List.class) and zero or more type parameters (either as Class es to resolve, or as ResolvedType s), resolves type information

Result in all these cases is an instance of ResolvedType, which you can think of as generic type information containing replacement for java.lang.Class. It is also the starting point for resolving member (constructor, field, method) information.

Resolving Type parameters for a class

While finding type parameters for specific class is relatively easy (using getTypeParameters), what you more commonly need to know is type parameters for a type implemented or extended. Specifically, consider case of:

public class StringIntMap extends HashMap<String,Integer> { }

where you would want to know key and value types of your Map sub-type. The first step is the same:

ResolvedType type = typeResolver.resolve(StringIntMap.class);

and to find parameter bindings for java.util.Map, you will use:

List<ResolvedType> mapParams = type.typeParametersFor(Map.class);
ResolvedType keyType = mapParams.get(0);
ResolvedType valueType = mapParams.get(1);

Note: if types were left unspecified (like, say, public class MyMap<K,V> extends Map<K,V>), you will always get resolved types based on bounds: in this case, it would be equivalent to parameterization of Map<Object,Object).

Resolving Member information

Member information resolution is done by com.fasterxml.classmate.MemberResolver, which takes a ResolvedType and produces ResolvedTypeWithMembers. As with TypeResolver, a single instance is typically shared by all code; but since no reuse of information is done, creating new instances is cheap and need not be avoided.

There are a few configuration options that can be used to determine things like:

  • Whether to include information from java.lang.Object (default: ignore and do not include)
  • Which members to filter out before aggregation (default: no filtering, include all members)
  • Which annotations to include in resolved members (default: include nothing)
  • For method annotations included, whether annotations from overridden methods are be inherited by overriding methods.
  • Which annotation overrides (aka "mix-ins") to use for which classes (default: no overrides)

ResolvedTypeWithMembers has simple accessors for:

  • Constructors: only constructors of the resolved type itself included (no constructors of superclasses)
  • Fields: all fields from resolved type and its superclasses are included; expect in cases where fields are masked, in which case masked fields (super-class field with same name as a field on its sub-class) are not included.
  • Static methods: only methods declared by resolved type itself
  • Member methods: all methods from resolved type and its supertypes are included; except for overriding in which case only overriding method is included (which also means that methods from interfaces are typically not included, when implementing class has overriding method intance)

Annotations of all member types can be overridden by annotation overrides; annotation value defaulting only works for members that use inheritance, meaning just member methods.

Member information is lazily constructed. Access to member information is synchronized such that it is safe to share ResolvedTypeWithMembers instances.

Examples

The following examples are all backed by an accompanying junit test

Resolving Classes

Resolve List.class
TypeResolver typeResolver = new TypeResolver();
// listType => List<Object>
ResolvedType listType = typeResolver.resolve(List.class);
Resolve List<String>.class
// listType => List<String>
ResolvedType listType = typeResolver.resolve(List.class, String.class);
Resolve List<String>.class (leveraging already ResolvedType object)
ResolvedType stringType = typeResolver.resolve(String.class);
// listType => List<String>
ResolvedType listType = typeResolver.resolve(List.class, stringType);
Resolve List<String>.class using "super type token"
// listType => List<String>
ResolvedType listType = typeResolver.resolve(new GenericType<List<String>>() {});

Resolving Members (i.e., Field/Method/Constructor)

Resolving All Members

Resolve ArrayList<String> static/instance Methods
ResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);
MemberResolver memberResolver = new MemberResolver(typeResolver);
ResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);
// get static methods
ResolvedMethod[] staticArrayListMethods = arrayListTypeWithMembers.getStaticMethods();
// get instance methods
ResolvedMethod[] arrayListMethods = arrayListTypeWithMembers.getMemberMethods();
Resolve ArrayList<String> Fields
ResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);
MemberResolver memberResolver = new MemberResolver(typeResolver);
ResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);
// get static/instance fields
ResolvedField[] arrayListFields = arrayListTypeWithMembers.getMemberFields();
Resolve ArrayList<String> Constructors
ResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);
MemberResolver memberResolver = new MemberResolver(typeResolver);
ResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);
// get static/instance fields
ResolvedConstructor[] arrayListConstructors = arrayListTypeWithMembers.getConstructors();

Resolving Particular Members (i.e., Filtering)

Resolve ArrayList<String>#size() Method
ResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);
MemberResolver memberResolver = new MemberResolver(typeResolver);
memberResolver.setMethodFilter(new Filter<RawMethod>() {
    @Override public boolean include(RawMethod element) {
        return "size".equals(element.getName());
    }
});
ResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);
ResolvedMethod sizeMethod = arrayListTypeWithMembers.getMemberMethods()[0];
Resolve ArrayList<String>.size Field
ResolvedType arrayListType = typeResolver.resolve(ArrayList.class, String.class);
MemberResolver memberResolver = new MemberResolver(typeResolver);
memberResolver.setFieldFilter(new Filter<RawField>() {
    @Override public boolean include(RawField element) {
        return "size".equals(element.getName());
    }
});
ResolvedTypeWithMembers arrayListTypeWithMembers = memberResolver.resolve(arrayListType, null, null);
ResolvedField sizeField = arrayListTypeWithMembers.getMemberFields()[0];

Resolving Members and their Annotations

Classes for reference in the examples below:

@Retention(RetentionPolicy.RUNTIME)
public @interface Marker { }

@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MarkerA { }

public class SomeClass {
    @Marker @MarkerA
    public void someMethod() { }
}
public class SomeSubclass extends SomeClass {
    @Override
    public void someMethod() { }
}
Resolve SomeClass#someMethod()'s Annotations
ResolvedType someType = typeResolver.resolve(SomeClass.class);
MemberResolver memberResolver = new MemberResolver(typeResolver);
memberResolver.setMethodFilter(new Filter<RawMethod>() {
    @Override public boolean include(RawMethod element) {
        return "someMethod".equals(element.getName());
    }
});
AnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_BUT_DONT_INHERIT);
ResolvedTypeWithMembers someTypeWithMembers = memberResolver.resolve(someType, annConfig, null);
ResolvedMethod someMethod = someTypeWithMembers.getMemberMethods()[0];
Marker marker = someMethod.get(Marker.class);  // marker != null
MarkerA markerA = someMethod.get(MarkerA.class); // markerA != null
Resolve SomeSubclass#someMethod()'s Annotations
// setup removed for brevity; same as above only using SomeSubclass instead of SomeClass

AnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_BUT_DONT_INHERIT);
ResolvedTypeWithMembers someSubclassTypeWithMembers = memberResolver.resolve(someSubclassType, annConfig, null);
ResolvedMethod someMethod = someSubclassTypeWithMembers.getMemberMethods()[0];
Marker marker = someMethod.get(Marker.class);  // marker == null
MarkerA markerA = someMethod.get(MarkerA.class); // markerA == null
Override override = someMethod.get(Override.class); // override == null (RetentionPolicy = SOURCE)
Resolve SomeSubclass#someMethod()'s Annotations including @Inherited
// setup removed for brevity; same as above

AnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT_IF_INHERITED);
ResolvedTypeWithMembers someSubclassTypeWithMembers = memberResolver.resolve(someSubclassType, annConfig, null);
ResolvedMethod someMethod = someSubclassTypeWithMembers.getMemberMethods()[0];
Marker marker = someMethod.get(Marker.class);  // marker == null
MarkerA markerA = someMethod.get(MarkerA.class); // markerA != null
Override override = someMethod.get(Override.class); // override == null (RetentionPolicy = SOURCE)
Resolve SomeSubclass#someMethod()'s Annotations including all super class's Annotations
// setup removed for brevity; same as above

AnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT);
ResolvedTypeWithMembers someSubclassTypeWithMembers = memberResolver.resolve(someSubclassType, annConfig, null);
ResolvedMethod someMethod = someSubclassTypeWithMembers.getMemberMethods()[0];
Marker marker = someMethod.get(Marker.class);  // marker != null
MarkerA markerA = someMethod.get(MarkerA.class); // markerA != null
Override override = someMethod.get(Override.class); // override == null (RetentionPolicy = SOURCE)

Using Annotation "mix-ins"

Types with the same method signature, field definition or constructor signature but which aren't explicitly related to one another (i.e., extend each other or implement the same interface) can have their annotations "mixed in" to others' resolved types. For example, using the SomeClass from above, let's add another class definition.

public class SomeOtherClass {
    public void someMethod() { }
}

The someMethod signature on SomeOtherClass is the same as SomeClass however SomeOtherClass does not extend from SomeClass. Member resolution for SomeOtherClass, like we've done above, will (of course) result in no Annotations.

// setup removed for brevity; similar to above but using SomeOtherClass

AnnotationConfiguration annConfig = new AnnotationConfiguration.StdConfiguration(AnnotationInclusion.INCLUDE_AND_INHERIT);
ResolvedTypeWithMembers someOtherClassTypeWithMembers = memberResolver.resolve(someOtherClassType, annConfig, null);
ResolvedMethod someMethod = someOtherClassTypeWithMembers.getMemberMethods()[0];
Marker marker = someMethod.get(Marker.class);  // marker == null, of course
MarkerA markerA = someMethod.get(MarkerA.class); // markerA == null, of course

We can augment the annotations returned by SomeOtherClass with "mix-ins"

// setup removed for brevity; same as above, using SomeOtherClass

// MIX-IN -> take SomeClass and apply to SomeOtherClass
AnnotationOverrides annOverrides = AnnotationOverrides.builder().add(SomeOtherClass.class, SomeClass.class).build();

ResolvedTypeWithMembers someOtherTypeWithMembers = memberResolver.resolve(someOtherType, annConfig, annOverrides);
ResolvedMethod someMethod = someOtherTypeWithMembers.getMemberMethods()[0];
Marker marker = someMethod.get(Marker.class);  // marker != null
MarkerA markerA = someMethod.get(MarkerA.class); // markerA != null

Now the ResolvedMethod for SomeOtherClass also contains the Marker and MarkerA annotations!

More Repositories

1

jackson

Main Portal page for the Jackson project
8,671
star
2

jackson-databind

General data-binding package for Jackson (2.x): works on streaming API (core) implementation(s)
Java
3,429
star
3

jackson-core

Core part of Jackson that defines Streaming API as well as basic shared abstractions
Java
2,208
star
4

jackson-module-kotlin

Module that adds support for serialization/deserialization of Kotlin (http://kotlinlang.org) classes and data classes.
Kotlin
1,082
star
5

jackson-annotations

Core annotations (annotations that only depend on jackson-core) for Jackson data processor
Java
999
star
6

jackson-docs

Documentation for the Jackson JSON processor.
695
star
7

jackson-dataformat-xml

Extension for Jackson JSON processor that adds support for serializing POJOs as XML (and deserializing from XML) as an alternative to JSON
Java
550
star
8

jackson-module-scala

Add-on module for Jackson (https://github.com/FasterXML/jackson) to support Scala-specific datatypes
Scala
494
star
9

jackson-modules-java8

Set of support modules for Java 8 datatypes (Optionals, date/time) and features (parameter names)
Java
392
star
10

jackson-dataformats-text

Uber-project for (some) standard Jackson textual format backends: csv, properties, yaml (xml to be added in future)
Java
383
star
11

jackson-module-jsonSchema

Module for generating JSON Schema (v3) definitions from POJOs
Java
358
star
12

jackson-datatype-hibernate

Add-on module for Jackson JSON processor which handles Hibernate (https://www.hibernate.org/) datatypes; and specifically aspects of lazy-loading
Java
307
star
13

jackson-dataformats-binary

Uber-project for standard Jackson binary format backends: avro, cbor, ion, protobuf, smile
Java
297
star
14

aalto-xml

Ultra-high performance non-blocking XML processor (Stax API + extensions)
Java
286
star
15

jackson-jr

Stand-alone data-binding module designed as a light-weight (and -featured) alternative to `jackson-databind`: will only deal with "Maps, Lists, Strings, wrappers and Java Beans" (jr-objects), or simple read-only trees (jr-stree)
Java
224
star
16

woodstox

The gold standard Stax XML API implementation. Now at Github.
Java
210
star
17

jackson-dataformat-csv

(DEPRECATED) -- moved under: https://github.com/FasterXML/jackson-dataformats-text
Java
194
star
18

jackson-modules-base

Uber-project for foundational modules of Jackson that build directly on core components but nothing else; not including data format or datatype modules
Java
163
star
19

jackson-dataformat-yaml

Jackson module to add YAML backend (parser/generator adapters)
Java
139
star
20

jackson-datatype-joda

Extension module to properly support full datatype set of Joda datetime library
Java
138
star
21

jackson-jaxrs-providers

Multi-module project that contains Jackson-based "old" JAX-RS (ones under `javax.ws.rs`) providers for JSON, XML, YAML, Smile, CBOR formats
Java
107
star
22

jackson-datatype-jsr310

(DEPRECATED) -- moved under `jackson-modules-java8` repo: https://github.com/FasterXML/jackson-modules-java8
Java
92
star
23

jackson-module-afterburner

(DEPRECATED) -- moved under `jackson-modules-base`
Java
91
star
24

smile-format-specification

New home for Smile format (https://en.wikipedia.org/wiki/Smile_(data_interchange_format))
87
star
25

jackson-datatypes-collections

Jackson project that contains various collection-oriented datatype libraries: Eclipse Collections, Guava, HPPC, PCollections
Java
73
star
26

jackson-datatype-guava

(DEPRECATED) -- moved under `jackson-datatypes-collections`
Java
68
star
27

jackson-datatype-jdk8

(DEPRECATED) -- moved under `jackson-modules-java8`
Java
58
star
28

jackson-datatype-json-org

(DEPRECATED) Support for org.json data types, to ease migration out of code that uses them
Java
50
star
29

jackson-bom

Bill of materials POM for Jackson projects
Logos
49
star
30

jackson-dataformat-smile

(DEPRECATED) -- moved under `jackson-dataformats-binary
Java
44
star
31

jackson-module-jaxb-annotations

(DEPRECATED!!!) Moved to: https://github.com/FasterXML/jackson-modules-base/
Java
43
star
32

StaxMate

StaxMate: Automatic Shifting for Streaming XML Processing
Java
41
star
33

jackson-dataformat-cbor

(DEPRECATED) -- moved under `jackson-dataformats-binary`
Java
38
star
34

jackson-dataformat-avro

(DEPRECATED) -- moved under `jackson-dataformats-binary
Java
38
star
35

stax2-api

Extension API for Stax, Java pull-parsing API (STreaming Api for Xml)
Java
36
star
36

jackson-module-parameter-names

(DEPRECATED) -- moved under `jackson-modules-java8`
Java
33
star
37

jackson-dataformat-protobuf

(DEPRECATED) -- moved under `jackson-dataformats-binary`
Java
32
star
38

jackson-module-mrbean

(DEPRECATED) -- moved under `jackson-modules-base`
Java
27
star
39

TransiStore

Distributed data store for transient (temporary, time-bound) data. Based on ClusterMate/StoreMate
Java
21
star
40

jackson-datatype-jsr353

(DEPRECATED) -- moved under `jackson-datatypes-misc` https://github.com/FasterXML/jackson-datatypes-misc/
Java
19
star
41

jackson-future-ideas

Repository for SOLE PURPOSE of issue tracker and Wiki for NEW IDEAS. Please: NO BUG REPORTS.
18
star
42

jackson-datatypes-misc

Collection of common Jackson datatype modules not part of other multi-project repos
Java
17
star
43

jackson-benchmarks

Project that contains JMH-based micro-benchmarks to help with optimizations
Java
14
star
44

jackson-dataformat-properties

(DEPRECATED) -- moved under `jackson-dataformats-text`
Java
13
star
45

jackson-jakarta-rs-providers

Multi-module project that contains Jackson-based "new" Jakarta-RS (nee "JAX-RS" -- ones under `jakarta.ws.rs`) providers for JSON, XML, YAML, Smile, CBOR formats
Java
10
star
46

jackson-datatype-hppc

(DEPRECATED) -- moved under `jackson-datatypes-collections`
Java
9
star
47

oss-parent

Grandpa pom for all projects under FasterXML git umbrella
8
star
48

jackson-datatype-jdk7

(DEPRECATED) -- included in `jackson-databind` as of Jackson 2.7
Java
7
star
49

jvm-json-benchmark

Performance benchmark suite that compares data-binding (JSON<->POJO) performance of Java JSON libraries. Uses Japex benchmark framework for running tests and visualizing results.
Java
7
star
50

Hacktoberfest2020

Central repository for FasterXML activities related to Hacktoberfest 2020 by DigitalOcean (https://hacktoberfest.digitalocean.com/)
6
star
51

jackson-module-guice

(DEPRECATED) -- moved under `jackson-modules-base`
Java
5
star
52

jackson3-dev

Repository for planning and tracking development of Jackson 3.0, with bigger API changes
5
star
53

jackson-module-paranamer

(DEPRECATED) -- moved under `jackson-modules-base`
Java
5
star
54

jackson-parent

Parent pom for all core Jackson components (but only those -- users should use `jackson-bom`)
5
star
55

jackson-schema-maven-plugin

Maven plug-in for generation JSON Schemas using Jackson library and extension modules
Java
4
star
56

jackson-jdk11-compat-test

Test project for verifying Jackson's support of JDK9+ Module system
Java
3
star
57

jackson-dataformat-thrift

Not Yet A Thing -- placeholder for possible future implementation
Java
3
star
58

jackson-integration-tests

Project that contains integration tests across Jackson components
Java
3
star
59

jackson-jdk17-compat-test

Test suite for JDK 16 compatibility of Jackson components, mainly jackson-databind
Java
3
star
60

jackson-tools

Collection of command-line tools related to Jackson data processor, such as format decoders
Java
2
star
61

jackson-dataformat-ini

(Not Yet a Thing -- Placholder!) Data format implementation for "ini files", used on Windows, Python
Java
2
star
62

jackson-jdk6-compat-test

Test project to verify JDK6 compatibility of Jackson versions 2.7 and anbove
Java
2
star
63

OmniPipe

Distributed data queue implementation that builds on ClusterMate/StoreMate foundation
2
star
64

jackson-module-osgi

(DEPRECATED) -- moved under `jackson-modules-base`
Java
2
star
65

jackson-gh-actions

Repository for reusable Github workflow actions for Jackson project
2
star
66

Woodstox4

Backup repository for older versions of Woodstox (pre-5.0), migrated from Codehaus
Java
1
star