java源文件编译成jar_从源文件和JAR文件构建Java代码模型

java源文件编译成jar

最近,我花了一些时间来研究有效java ,该方法正在GitHub上达到300星(可以免费帮助实现目标:D)。

Effectivejava是在您的Java代码上运行查询的工具。 它基于我参与的另一个项目javaparser 。 Javaparser将Java源代码作为输入,并生成一个抽象语法树(AST)。 我们可以直接在AST上执行简单的分析。 例如,我们可以找出哪些方法采用超过5个参数(您可能希望对其进行重构……)。 但是,更复杂的分析要求解析符号

在这篇文章中,我将介绍在考虑源代码和JAR文件的情况下如何实现符号解析。 在第一篇文章中,我们将在源代码和JAR文件上建立同质视图,在下一篇文章中,我们将探索这些模型来解决这些符号。

代码可在GitHub上的有效Java的分支symbolsolver中获得。

解析符号

出于什么原因,我们需要解析符号?

给出以下代码:

foo.method(a, b, c);

我们需要弄清楚foomethodabc是什么。 它们是否引用局部变量? 给当前方法的参数? 到在类中声明的字段? 要从超类继承的字段? 他们有什么类型? 为了回答这个问题,我们需要能够解析符号。

为了解决符号,我们可以浏览AST并应用作用域规则。 例如,我们可以查看某个符号是否对应于局部变量。 如果没有,我们可以在该方法的参数中查找。 如果仍然找不到对应关系,则需要在类声明的字段中查找,如果仍然不走运,则可能必须在此类继承的字段中走运。

现在,作用域规则比我刚刚描述的一小步要复杂得多。 由于重载,解决方法特别复杂。 但是,一个关键点是,要解决符号,我们通常需要在导入的类,扩展的类和外部类中进行查找,这些类可能是项目的一部分,也可以作为依赖项导入。

因此,要解决符号,我们需要寻找相应的声明:

  1. 根据我们正在检查的项目类别的AST
  2. 在用作依赖项的JAR文件中包含的类中

Javaparser为我们提供了第一点所需的AST,对于第二点,我们将使用Javassist在JAR文件中构建类的模型。

建立JAR文件中包含的类的模型

我们的符号求解器应按顺序在条目列表(我们的类路径条目)中查找,并查看是否可以在其中找到某个类。 为此,我们需要打开JAR文件并在其内容中查找。 出于性能原因,我们可能希望构建给定JAR中包含的元素的缓存。

(ns app.jarloading(:use [app.javaparser])(:use [app.operations])(:use [app.utils])(:import [app.operations Operation]))(import java.net.URLDecoder)
(import java.util.jar.JarEntry)
(import java.util.jar.JarFile)
(import javassist.ClassPool)
(import javassist.CtClass); An element on the classpath (a single class, interface, enum or resource file)
(defrecord ClasspathElement [resource path contentAsStreamThunk])(defn- jarEntryToClasspathElement [jarFile jarEntry](let [name (.getName jarEntry)content (fn [] (.getInputStream jarFile jarEntry))](ClasspathElement. jarFile name content)))(defn getElementsEntriesInJar"Return a set of ClasspathElements"[pathToJarFile](let [url (URLDecoder/decode pathToJarFile "UTF-8")jarfile (new JarFile url)entries (enumeration-seq (.entries jarfile))entries' (filter (fn [e] (not (.isDirectory e))) entries )](map (partial jarEntryToClasspathElement jarfile) entries')))(defn getClassesEntriesInJar"Return a set of ClasspathElements"[pathToJarFile](filter (fn [e] (.endsWith (.path e) ".class")) (getElementsEntriesInJar pathToJarFile)))(defn pathToTypeName [path](if (.endsWith path ".class")(let [path' (.substring path 0 (- (.length path) 6))path'' (clojure.string/replace path' #"/" ".")path''' (clojure.string/replace path'' "$" ".")]path''')(throw (IllegalArgumentException. "Path not ending with .class"))))(defn findEntry"return the ClasspathElement corresponding to the given name, or nil"[typeName classEntries](first (filter (fn [e] (= typeName (pathToTypeName (.path e)))) classEntries)))(defn findType"return the CtClass corresponding to the given name, or nil"[typeName classEntries](let [entry (findEntry typeName classEntries)classPool (ClassPool/getDefault)](if entry(.makeClass classPool ((.contentAsStreamThunk entry)))nil)))

我们如何开始? 首先,我们阅读jar中列出的条目( getElementEntriesInJar )。 这样,我们得到了ClasspathElements的列表。 然后,我们仅关注.class文件( getClassesEntriesInJar )。 每个jar应调用一次此方法,并且应将结果缓存。 给定ClasspathElement列表,然后我们可以搜索与给定名称对应的元素(例如com.github.javaparser.ASTParser )。 为此,我们可以使用方法findEntry 。 或者,我们也可以使用Javassist加载该类: findType方法执行的操作,返回CtClass的实例。

为什么不仅仅使用反射?

有人可能会认为,仅在有效java的类路径中添加依赖项,然后使用常规的类加载器和反射来获取所需的信息会更容易。 虽然这会更容易,但是存在一些缺点:

  1. 当加载一个类时,将执行静态初始化程序,这可能不是我们想要的
  2. 它可能与有效Java的实际依赖项冲突。
  3. 最后,并非所有字节码中可用的信息都可以通过反射API轻松检索到

解决符号:结合异构模型

现在,要解决符号问题,我们将必须实现作用域规则,并浏览从Javaparser获得的AST和从Javassist获得的CtClass 。 我们将在以后的博客文章中看到详细信息,但是我们需要首先考虑另一个方面。 考虑以下代码:

package me.tomassetti;import com.github.someproject.ClassInJar;public class MyClass extends ClassInJar {private int myDeclaredField;public int foo(){return myDeclaredField + myInheritedField;}
}

在这种情况下,我们假设有一个包含类com.github.someproject.ClassInJar的JAR,该类声明了字段myInheritedField 。 当我们求解符号时,将具有以下映射:

  • myDeclaredField将被解析为com.github.javaparser.ast.body.VariableDeclarator的一个实例(在JavaParser类我们有映射到结构,如私人INT A,B,C型FieldDeclaration的节点; VariableDeclarators代替点到单个字段例如abc
  • myInheritedField将解析为javassist.CtField的实例

问题在于我们希望能够以同质的方式对待它们:我们应该能够使用相同的函数来对待每个字段,而不管它们的起源(JAR文件还是Java源文件)。 为此,我们将使用clojure 协议构建通用视图。 我倾向于将clojure的协议视为与Java 接口等效。

(defprotocol FieldDecl(fieldName [this]))(extend-protocol FieldDeclcom.github.javaparser.ast.body.VariableDeclarator(fieldName [this](.getName (.getId this))))(extend-protocol FieldDecljavassist.CtField(fieldName [this](.getName this)))

在Java中,我们必须构建适配器,实现新的接口( FieldDecl )并将现有的类( VariableDeclaratorCtField )包装在Clojure中,我们只能说这些类扩展了协议,我们已经完成了。

现在我们可以将每个字段都视为fieldDecl ,并且可以在每个字段上调用fieldName 。 我们仍然需要弄清楚如何解决字段类型 。 为此,我们需要研究符号解析,尤其是类型解析,这是我们的下一步。

结论

Java代码的构建模型使我着迷了一段时间。 作为我的硕士论文的一部分,我写了一个与现有Java代码交互的DSL(我也有编辑器,写为Eclipse插件和代码生成器:这很酷)。 在DSL中,可以使用源代码和JAR文件指定对Java类的引用。 我使用的是EMF,并且可能在该项目中采用了JaMoPP和Javassist。

后来,我建立了CodeModels库,以分析几种语言(Java,JavaScript,Ruby,Html等)的AST。

我认为构建用于操作代码的工具是元编程的一种非常有趣的形式,并且应该在每个开发人员的工具箱中。 我计划花更多的时间来使用有效的java。 有趣的时刻来了。

随时分享评论和建议!

翻译自: https://www.javacodegeeks.com/2015/08/building-models-of-java-code-from-source-and-jar-files.html

java源文件编译成jar

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337187.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【从零开始学C语言】知识总结一:C语言的基本知识汇总

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删C语言是一种计算机程序设计语言。它既有高级语言的特点,又具有汇编语言的特点。它可以作 为系统设计语言,编写工作系统应…

排球分组循环交叉编排_同学!中国海洋大学第一届排球联赛等你来战!

New中国海洋大学第一届排球联赛开始啦比赛宗旨1亲爱的同学们:为增强学生凝聚力,加强新老生交流,促进各院系的友谊,培养同学们的团队精神,丰富同学们的课余生活,展示我校文体风采,特此举办本次中…

jolokia_使用WildFly 9和Jolokia监视DevOps样式

jolokiaDevOps是当今最热门的话题之一。 并且围绕它的广泛主题使您很难真正找到完整的描述或涵盖体面粒度的所有内容。 可以肯定的一件事是:最重要的部分之一是提供正确的度量标准和信息以监视应用程序。 Java EE和JMX 监视Java EE服务器的标准方法是JMX。 使用JCo…

计算机的本质是哲学

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删学什么抽象模型庄子说过吾生有崖,知无涯。以有限的生命去学习无尽的知识是很愚蠢的。所以,学习的终极目标一定不是知识本…

用户首次登录之前必须更改密码_技术丨带你玩转Win10系统的用户账户

由于微软关于Win10家庭版系统用户和组的功能设置,在一般情况下,用户无法直接进行用户账户的管理。但通过简单的设置,同样能够玩转Win10系统的用户账户。今天我们将探索并学习:如何实现用户账户的设置与更改。Microsoft账户登录首次…

mac 大写锁定延迟_延迟分析中的案例研究:锁定与同步

mac 大写锁定延迟特别是在这篇文章中,我们将讨论: java.concurrent.Lock创建的垃圾 比较锁与同步 如何以编程方式测量延迟 争用对锁和同步的影响 遗漏对延迟测试的影响 回到我最喜欢的主题之一,垃圾创建/分配。 有关此主题的更多详细信…

很好玩的12个c语言面试题

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删12个C语言面试题,涉及指针、进程、运算、结构体、函数、内存,看看你能做出几个!1.gets()函数问:请…

python 百分比数据_如何使用python计算数据列相对于另一列的百分比排名

这是一个解决方案。整理训练数据。然后对验证数据使用searchsorted。import pandas as pdimport numpy as np# Generate Dummy Datadf_train pd.DataFrame({Values: 1000*np.random.rand(15712)})#Sort Datadf_train df_train.sort_values(Values)# Calculating Rank and Ran…

java 开发 jvm_Java开发人员应了解的JVM流行语

java 开发 jvm本文将与您分享一些JVM“流行语”,它们对于Java开发人员在执行任何JVM性能和垃圾回收调优之前理解和记住非常重要。 本文末尾还提供了一些技巧,包括一些高级性能调优最佳实践。 将来的文章中将探讨有关Oracle HotSpot并发GC收集器&#xff…

C/C++在Java、Android和Objective-C三大平台下实现混合编程

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删Android和iOS开发都支持C开发,可以一套代码多平台使用。同时C难以反编译的特性也可以为Android开发带来代码的保密,另一n…

Linux Shell 004-四则运算

Linux Shell 004-四则运算 本节关键字:Linux、Bash Shell、四则运算 相关指令:echo、let、set、unset Bash Shell支持的四则运算 算术运算:默认情况下,shell就只能支持简单的整数运算 运算内容:加(&…

vs不一致的行尾对话框怎么调出_SolidWorks工程图打开后图纸没有了空白了怎么办?还能找回来吗?...

SolidWorks工程图打开后图纸没有了空白了怎么办?还能找回来吗?答案是肯定的。不知道大家使用SolidWorks有没有遇到这种情况,如下图所示:就是我们本来画好标注好的工程图,竟然没了,怎么造成的呢?…

jpa 忽略bean_在WildFly上将JPA和CDI Bean与骆驼一起使用

jpa 忽略bean我并没有真正为此计划,但是在一个免费的会议月份中,我有机会进行了一些深入的探讨,并向您展示了WildFly-Camel子系统提供的WildFly魔术上的更多Camel。 商业背景 该演示来自Christina Lin在JBoss Demo-Central上的一个演示 。 她…

【如何系统地学习 C++ 语言】关于C++,有哪些你需要提前知道的知识?

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删C是一种通用的、面向对象的编程语言,可用于开发操作系统、游戏、图形用户界面、后端以及高性能系统和应用程序。所以,尽管…

python rsa加密之后byte类型存储到数据库中_python3 rsa加密

遇到了跟你一样的问题。 此js封装的源码 如下。希望看到的大神解决了的话帮我一下。/*RSA, a suite of routines for performing RSA public-key computations in JavaScript.Copyright 1998-2005 David Shapiro.Dave Shapirodaveohdave.comchanged by Fuchun, 2010-05-06fcrpg…

jdk 11 模块系统_JDK 9:模块系统状态的重点

jdk 11 模块系统马克雷因霍尔德 ( Mark Reinhold )的“模块系统状态 (SOMS)”已于本月初发布,它提供了信息丰富的可读性“对Jigsaw项目中原型的Java SE平台进行了增强的非正式概述,并被提议作为JSR 376的起…

【如何系统地学习 C++ 语言】从开发环境到C++进阶,应该怎么办?

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删开发环境如前面介绍的那样,C属于一种静态的编译型语言,所以,开发环境配置过程中就需要用到对应的编译器。C有…

小学生在家自学python_小学生都能学会的python(函数)

小学生都能学会的python(函数)神马是函数函数: 对功能或者动作的封装函数的定义def 函数名(形参列表):函数体(return)ret 函数名(实参列表)函数的返回值return,只要执行到return 函数的本次调用就会被停止1.如果函数不写return, 没有返回值。…

高度可定制化的方案_如何开发高度可定制的产品

高度可定制化的方案您是否听说过:“我们非常喜欢您的产品……除了一些小细节。”? 然后,CIO推出了一系列其他“必备”要求的清单,其中有数百个要添加到您的惊人产品中。 您是否听说过,甚至说过:“团队&…

文言文编程?厉害了程序员!

点击蓝字关注我们因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络,侵删你能看出来,这首诗妙在哪里吗?来源:量子位(ID:QbitAI),梦晨 萧…