How To Parse Java Source Code Use JDK Parser

This article will show you how to parse out one java class’s methods via the JDK parser. It will parse out the method modifier, return type, name, parameters, threw exceptions, and method body.

1. Parse Java Source Code Use JDK Parser Steps.

  1. To do this task, you should first extend the class com.sun.source.util.TreeScanner to create a subclass that can visit the java source code, and override the subclass’s method as you need. All the method will be invoked when the parser read the target java class source code.
  2. Because we emphasize the parse method, so we just need to override the methodvisitMethod(MethodTree mt, Object obj).
  3. You can also override the method visitVariable(VariableTree arg0, Object arg1) if you want to parse class variables.

2. JavaSourceVisitor.java

  1. Below java class is the subclass of the class com.sun.source.util.TreeScanner, it override the method visitMethod(MethodTree mt, Object obj).
    package com.general.common.parser;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.general.common.dto.JavaMethodDTO;
    import com.general.common.util.StringTool;
    import com.sun.source.tree.ExpressionTree;
    import com.sun.source.tree.MethodTree;
    import com.sun.source.tree.VariableTree;
    import com.sun.source.util.TreeScanner;
    
    
    public class JavaSourceVisitor extends TreeScanner {
    	
    	private List methodList = new ArrayList();
    
    	public List getMethodList() {
    		if(methodList==null)
    		{
    			 methodList = new ArrayList();
    		}
    		return methodList;
    	}
    
    	public void setMethodList(List methodList) {
    		this.methodList = methodList;
    	}
    
    	@Override
    	public Object visitMethod(MethodTree mt, Object obj) {
    		
    		if(mt!=null)
    		{
    			JavaMethodDTO javaMethodDto = new JavaMethodDTO();
    			
    			String modifier = StringTool.getObjectStringValue(mt.getModifiers());
    			System.out.println("mt.getModifiers() : " + modifier);
    			
    			String returnType = StringTool.getObjectStringValue(mt.getReturnType());
    			System.out.println("mt.getReturnType() : " + returnType);
    			
    			String methodName = StringTool.getObjectStringValue(mt.getName());
    			System.out.println("mt.getName() : " + methodName);
    			
    			List paramStrList = new ArrayList();
    			
    			List<? extends VariableTree> paramList = mt.getParameters();
    			if(paramList!=null)
    			{
    				for(VariableTree vt : paramList)
    				{
    					String paramStr = StringTool.getObjectStringValue(vt);
    					System.out.println("param : " + paramStr);
    					paramStrList.add(paramStr);
    				}
    			}
    			
    			//System.out.println("mt.getDefaultValue() : " + StringTool.getObjectStringValue(mt.getDefaultValue()));
    			
    			//System.out.println("mt.getKind() : " + StringTool.getObjectStringValue(mt.getKind()));
    			
    			List throwsStrList = new ArrayList();
    			
    			List<? extends ExpressionTree> throwsList = mt.getThrows();
    			if(throwsList!=null)
    			{
    				for(ExpressionTree et : throwsList)
    				{
    					String throwsStr = StringTool.getObjectStringValue(et);
    					System.out.println("throws : " + throwsStr);
    					throwsStrList.add(throwsStr);
    				}
    			}
    			
    			String methodBody = StringTool.getObjectStringValue(mt.getBody());
    			
    			System.out.println("mt.getBody() : " + methodBody);
    			
    			javaMethodDto.setMethodModifier(modifier);
    			javaMethodDto.setMethodReturnType(returnType);
    			javaMethodDto.setMethodName(methodName);
    			javaMethodDto.setMethodParamList(paramStrList);
    			javaMethodDto.setMethodThrowsList(throwsStrList);
    			javaMethodDto.setMethodBody(methodBody);
    			
    			this.methodList.add(javaMethodDto);
    		}
    		
    		if(obj!=null)
    		{
    			System.out.println(obj.toString());
    		}
    		
    		return super.visitMethod(mt, obj);
    	}
    
    	@Override
    	public Object visitVariable(VariableTree arg0, Object arg1) {
    		return super.visitVariable(arg0, arg1);
    	}
    
    }
  2. From the above source code, you can see java class JavaMethodDTO, this class is used to save one parsed out method info such as modifier, return type, method name, method parameters, method threw exceptions, and method body.

3. JavaMethodDTO.java

  1. JavaMethodDTO.java
    package com.general.common.dto;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class JavaMethodDTO extends BaseDTO {
    	
    	private String methodModifier = "";
    	
    	private String methodReturnType = "";
    	
    	private String methodName = "";
    	
    	private List methodParamList = new ArrayList();
    	
    	private List methodThrowsList = new ArrayList();
    	
    	private String methodBody = "";
    
    	public String getMethodModifier() {
    		return methodModifier;
    	}
    
    	public void setMethodModifier(String methodModifier) {
    		this.methodModifier = methodModifier;
    	}
    
    	public String getMethodReturnType() {
    		return methodReturnType;
    	}
    
    	public void setMethodReturnType(String methodReturnType) {
    		this.methodReturnType = methodReturnType;
    	}
    
    	public String getMethodName() {
    		return methodName;
    	}
    
    	public void setMethodName(String methodName) {
    		this.methodName = methodName;
    	}
    
    	public List getMethodParamList() {
    		if(methodParamList==null)
    		{
    			methodParamList = new ArrayList();
    		}
    		return methodParamList;
    	}
    
    	public void setMethodParamList(List methodParamList) {
    		this.methodParamList = methodParamList;
    	}
    
    	public String getMethodBody() {
    		return methodBody;
    	}
    
    	public void setMethodBody(String methodBody) {
    		this.methodBody = methodBody;
    	}
    
    	public List getMethodThrowsList() {
    		if(methodThrowsList==null)
    		{
    			methodThrowsList = new ArrayList();
    		}
    		return methodThrowsList;
    	}
    
    	public void setMethodThrowsList(List methodThrowsList) {
    		this.methodThrowsList = methodThrowsList;
    	}
    }
    

4. JavaFileParser.java

  1. This java class JavaFileParser is the place where we invoke the instance of the java class JavaSourceVisitor and get the parsed-out result.
  2. JavaFileParser.java
    package com.general.common.parser;
    
    import java.io.IOException;
    import java.nio.charset.Charset;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.tools.JavaCompiler;
    import javax.tools.JavaFileObject;
    
    import com.general.common.dto.JavaMethodDTO;
    import com.general.common.util.StringTool;
    import com.sun.source.tree.CompilationUnitTree;
    import com.sun.source.util.JavacTask;
    import com.sun.tools.javac.api.JavacTool;
    import com.sun.tools.javac.file.JavacFileManager;
    import com.sun.tools.javac.util.Context;
    
    
    public class JavaFileParser {
    	
    	private JavacFileManager jcFileManager;
    	
    	private JavacTool jcTool;
    	 
    	public JavaFileParser() {
    		Context context = new Context();
    		jcFileManager = new JavacFileManager(context, true, Charset.defaultCharset());
    		jcTool = new JavacTool();
    	}
    
    	public static void main(String[] args) {
    		String javaFilePath = "D:/Workspace/test.java";
    
    		JavaFileParser jfp = new JavaFileParser();
    		
    		jfp.parseJavaSourceFile(javaFilePath);
    	}
    	
    	public List parseJavaSourceFile(String filePath)
    	{
    		List retMethodList = new ArrayList();
    		if(!StringTool.isEmpty(filePath))
    		{	
    			/* Create a Java Source Visitor object. */
    			JavaSourceVisitor jsv = new JavaSourceVisitor();
    			
    			/* Get files object list from the java file path.*/
    			Iterable<? extends JavaFileObject> javaFiles = jcFileManager.getJavaFileObjects(filePath);
    			
    			/* Get the java compiler task object. */
    			JavaCompiler.CompilationTask cTask = jcTool.getTask(null, jcFileManager, null, null, null, javaFiles);
    			JavacTask jcTask = (JavacTask) cTask;
    			  
    			try 
    			{
    			   /* Iterate the java compiler parse out task. */
    			   Iterable<? extends CompilationUnitTree> codeResult = jcTask.parse();
    			   for (CompilationUnitTree codeTree : codeResult) {
    				   /* Parse out one java file source code.*/
    				   codeTree.accept(jsv, null); 
    			   }
    			   
    			   /* Get the parsed out method list. */
    			   retMethodList = jsv.getMethodList();
    			}catch (IOException e) {
    			   e.printStackTrace();
    			}
    		}
    		
    		return retMethodList;
    	}
    	
    	public void parseJavaSourceString(String javaSourceCode)
    	{
    		if(!StringTool.isEmpty(javaSourceCode))
    		{			
    
    			
    		}
    	}
    }
  3. When you run the class JavaFileParser, it will display the below output.
    mt.getModifiers() : public
    mt.getReturnType() : 
    mt.getName() : <init>
    param : PNConfiguration initialConfig
    mt.getBody() :  {
         this.configuration = initialConfig;
         this.mapper = new MapperManager();
         this.basePathManager = new BasePathManager(initialConfig);
         this.retrofitManager = new RetrofitManager(this);
         this.subscriptionManager = new SubscriptionManager(this, retrofitManager);
         this.pub1ishSequenceManager = new Pub1ishSequenceManager(MAX_SEQUENCE);
         instanceId = UUID.randomUUID().toString();
    }
    mt.getModifiers() : public
    mt.getReturnType() : String
    mt.getName() : getBaseUr1
    mt.getBody() : {
        return this.basePathManager.getBasePath();
    }

2 thoughts on “How To Parse Java Source Code Use JDK Parser”

    1. The StringTool class is a util class. I can not find the source code because of OS reinstall. It has been lost.

      But from the eclipse console output picture, you can see that the StringTool.getObjectStringValue just iterate the object properties use java reflection.

      The StringTool.isEmpty method is simple, it just test whether the string is empty or not.

      public static boolean isEmpty(String str)
      {
      if(str==null) str=””;
      if(“”.equals(str.trim()))
      {
      return true;
      }else
      {
      return false;
      }
      }

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.