在运行时获取变量的值

时间:2014-07-17 08:47:33

标签: java eclipse runtime eclipse-plugin

我目前正在使用Eclipse插件。该插件应该读取一个java类,并在运行时获取某个变量的值

java类的示例:

public class MyClass {

 private int aVariable;

public int getaVariable() {
    return aVariable;
}

public void setaVariable(int aVariable) {
    this.aVariable = aVariable;
}

private int doSomethinng (){
    setaVariable(10);
    int x = getaVariable();
    return x;
}

}

现在我的插件应该在RUNTIME 获取变量 x的值,并在eclipse控制台上打印(第一个)。 为了阅读这个类,我创建了一个Eclipse插件" Hello World Commands":

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.text.Document;

public class SampleHandler extends AbstractHandler {

  public Object execute(ExecutionEvent event) throws ExecutionException {
    // Get the root of the workspace
    IWorkspace workspace = ResourcesPlugin.getWorkspace();
    IWorkspaceRoot root = workspace.getRoot();
    // Get all projects in the workspace
    IProject[] projects = root.getProjects();
    // Loop over all projects
    for (IProject project : projects) {
      try {
        printProjectInfo(project);
      } catch (CoreException e) {
        e.printStackTrace();
      }
    }
    return null;
  }

  private void printProjectInfo(IProject project) throws CoreException,
      JavaModelException {
    System.out.println("Working in project " + project.getName());
    if (project.isNatureEnabled("org.eclipse.jdt.core.javanature")) {
      IJavaProject javaProject = JavaCore.create(project);
      printPackageInfos(javaProject);
    }
  }

  private void printPackageInfos(IJavaProject javaProject)
      throws JavaModelException {
    IPackageFragment[] packages = javaProject.getPackageFragments();
    for (IPackageFragment mypackage : packages) {
      if (mypackage.getKind() == IPackageFragmentRoot.K_SOURCE) {
        System.out.println("Package " + mypackage.getElementName());
        printICompilationUnitInfo(mypackage);

      }

    }
  }

  private void printICompilationUnitInfo(IPackageFragment mypackage)
      throws JavaModelException {
    for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
      printCompilationUnitDetails(unit);

    }
  }

  private void printIMethods(ICompilationUnit unit) throws JavaModelException {
    IType[] allTypes = unit.getAllTypes();
    for (IType type : allTypes) {
      printIMethodDetails(type);
    }
  }

  private void printCompilationUnitDetails(ICompilationUnit unit)
      throws JavaModelException {
    System.out.println("Source file " + unit.getElementName());
    Document doc = new Document(unit.getSource());
    System.out.println("Has number of lines: " + doc.getNumberOfLines());
    printIMethods(unit);
  }

  private void printIMethodDetails(IType type) throws JavaModelException {
    IMethod[] methods = type.getMethods();
    for (IMethod method : methods) {

      System.out.println("Method name " + method.getElementName());
      System.out.println("Signature " + method.getSignature());
      System.out.println("Return Type " + method.getReturnType());

    }
  }
} 

我可以获得信息包,行数,方法名称等。但问题是我想打印变量 AT RUNTIME 的值! 你能帮我吗?

1 个答案:

答案 0 :(得分:0)

这是一个经典的staticdynamic分析问题。目前,您的Eclipse插件正在静态查看项目,因为项目尚未执行。

对于您的示例MyClass,没有关联的主方法,因此无论如何您都无法实际运行项目。如果不添加驱动程序(调用此类的主方法),则无法进行动态分析。但是,如果您沿着动态分析路线走下去,您可能会考虑使用日志工具来检测MyClass以记录aVariable的运行时值(可能超过一个值!)。

对于静态分析,任何完整的答案都必须保守地报告aVariable可以是任何整数值,因为setaVariable方法是公共可访问的,并且可以传递任何整数值。如果我们将潜在的通话目标限制为仅doSomething,那么您可以报告10是唯一可能的值。最后,如果您确实有其他代码与此类一起使用,您可以从所有有效的程序入口点(主要方法或特定于应用程序的生命周期入口点)开始,并进行一些分析以查找doSomething和{{1从项目的其余部分调用。然后,您需要回溯数据流并控制流路径并执行一些symbolic execution以查找潜在的运行时值(同样可能有多个!)。

将以下主要方法视为驱动程序。

setaVariable

public static void main(String[] args){ Random rnd = new Random(); MyClass c = new MyClass(); if(rnd.nextBoolean()){ c.setaVariable(100); } else { c.doSomething(); } } 的运行时值是多少?它可以有两个值aVariable10。这是一个棘手的问题,并且已经进行了大量的研究。你试图解决的问题越准确,你就会感到更头痛。