我目前正在使用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 的值! 你能帮我吗?
答案 0 :(得分:0)
这是一个经典的static与dynamic分析问题。目前,您的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();
}
}
的运行时值是多少?它可以有两个值aVariable
或10
。这是一个棘手的问题,并且已经进行了大量的研究。你试图解决的问题越准确,你就会感到更头痛。