DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
The Latest "Software Integration: The Intersection of APIs, Microservices, and Cloud-Based Systems" Trend Report
Get the report
  1. DZone
  2. Coding
  3. Java
  4. Using Java Compiler Tree API to Extract Generics Types

Using Java Compiler Tree API to Extract Generics Types

Jakub Holý user avatar by
Jakub Holý
·
Feb. 13, 12 · Interview
Like (0)
Save
Tweet
Share
7.97K Views

Join the DZone community and get the full member experience.

Join For Free

i was looking for some way to extract information about types of elements in java collections/maps using generics (list<string>, map<string, mybean>) so that the users of the static jsf expression validator wouldn’t need to declare the type of the elements manually. one possible way to get this information is to process the source codes with the sun compiler tree api, available since jdk 6.

it might be best to go and check the resulting 263 lines of collectiongenericstypeexctractor.java now. the code is little ugly, largely due to the api being ugly.

overview

  1. javacompiler (compiler api) is used to compile the source codes that should be searched for generics
  2. a custom annotation provider (java annotation api) is used during the compilation to process the sources
  3. the processor only delegates to a custom treepathscanner (sun compiler tree api) whose visitmethod extracts all the information from the methodtree, using some dark magic to get fully qualified type names of the class and return type

limitations

  1. the compiler must be able to resolve all dependencies (imports) to be able to process the files
  2. it only works with sun jdk and its tools.jar must be on the class path (the compiler and annotation apis are a part of java specification but the compiler tree api is not and is thus vendor-specific)
  3. the code currently doesn’t handle getters inside nested/inner classes (it would need to check that it is such a class and replace the last . with $ in the name)

you’d better check the complete (short) code at github but if it’s too far for you :-) , here is the crucial piece:

@override
public object visitmethod(methodtree methodtree, trees trees) {
	string typenamequalified = getenclosingclassnameifavailable(trees);

	// skip or bad stuff happens (case: inside anonymous inner class)
	if (typenamequalified == null) {
		return super.visitmethod(methodtree, trees);
	}

	tree returntype = methodtree.getreturntype();   // null for void method
	if (getter(methodtree) && returntype instanceof parameterizedtypetree) {
		assert tree.kind.parameterized_type == returntype.getkind();
		parameterizedtypetree parametrizedreturntype = (parameterizedtypetree) returntype;

		typecategory category = detecttypecategory(parametrizedreturntype);
		if (category.iscollectionormap()) {
			tree valuetypeargument = parametrizedreturntype.gettypearguments().get(category.getvaluetypeargumentidx());
			final string qualifiedgenerictypename = getqualifiedtype(valuetypeargument);

			string methodjsfname = getmethodjsfname(methodtree);
			system.out.println("found " + typenamequalified + "." + methodjsfname + ".*=" + qualifiedgenerictypename);
			// unqualified name: ((identifiertree) valuetypeargument).getname().tostring();
		}
	}
	return super.visitmethod(methodtree, trees);
}

most of the code has been copied from the article source code analysis using java 6 apis by seema richard (4/2008).

conclusion

it’s possible to use the java compiler tree api to get the desired information but it is not exactly easy because the api os overly complex and undocumented. it would likely be better to use some decent open-source java parser.

from http://theholyjava.wordpress.com/2012/02/07/using-java-compiler-tree-api-to-extract-generics-types/

Java compiler Java (programming language) API Tree (data structure) Extract

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 7 Ways for Better Collaboration Among Your Testers and Developers
  • Integrating AWS Secrets Manager With Spring Boot
  • Isolating Noisy Neighbors in Distributed Systems: The Power of Shuffle-Sharding
  • Introduction to NoSQL Database

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: