爪哇岛。不解析CtExecutableReference类型和声明的类型,具体取决于环境(Docker和本地Spring引导)
你好
我在Java项目中使用Spoon分析库时遇到了一个非常奇怪的问题。 我在运行相同的代码时得到不同的解析结果,这些代码在不同的环境中使用Spoon Launcher
- 1环境-从Intellij IDEA本地运行的Spring启动项目
- 2环境-与在Docker容器中运行的Spring Boot项目相同
在本地运行的SpringBoot项目中——一切正常,但是当我在Docker中运行相同的代码时——我在CtExecutableReference.getType()
和CtExecutableReference.getDeclaredType()
中得到null
值
我在GitHub上开始发行-https://github.com/INRIA/spoon/issues/3926
以下是详细信息
我的勺子版本是8.2.0。(来自maven repo)
我正试图从this GitHub repository解析(构建AST)代码 我在解析this class时遇到困难 这里有以下几行
...
@Service
public class ValueServices {
private ValuesRepository valuesRepository;
private Queue<Values> queue;
@Autowired
public ValueServices(ValuesRepository valuesRepository) {
super();
this.valuesRepository = valuesRepository;
this.queue = new LinkedList<Values>();
}
public List<Values> getAllValues() {
List<Values> values = new ArrayList<>();
this.valuesRepository.findAll().forEach(values::add);
return values;
}
...
}
在Docker中运行我的项目时,当我运行分析并尝试为this.valuesRepository.findAll().forEach(values::add)
语句的findAll()
方法解析CtExecutableReference
时,我得到了null
和getDeclaredType()
的null
值。
在本地运行时getType()
和getDeclaredType()
都具有非空值
在解析其他项目中的其他类似代码块时,也会出现同样的问题。 例如here
@Service
public class BetService {
public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH";
public static final String DATE_FORMAT_NOW_WITH_HOUR_MIN = "yyyy-MM-dd HH:mm:ss";
private BetRepository betRepository;
@Autowired
public BetService(BetRepository betRepository) {
super();
this.betRepository = betRepository;
}
public List<Bet> getAllBets() {
List<Bet> bets = new ArrayList<Bet>();
this.betRepository.findAll().forEach(bets::add);
return bets;
}
}
在Docker中运行时,带有this.betRepository.findAll()
的语句在getType
和getDeclaredType
中都为空,但在本地环境中为ok
同时following code在两种环境中都能很好地解析
public class BetRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private BetRepository betRepository;
@Test
public void test() {
Bet bet = new Bet("2018-07-06 12:56", "WIN", 103333, 1082, 500.5);
entityManager.persist(bet);
entityManager.flush();
List<Bet> bets = betRepository.findByCustomerId(bet.getCustomerId());
assertThat(bet.getCustomerId() == bets.get(0).getCustomerId());
}
}
语句betRepository.findByCustomerId()
被解析为ok,并且在Docker和n local Spring引导运行中都有必要的类型信息
当从IDE运行测试中的代码或从IDE启动Spring Boot项目,并通过从Web UI调用服务初始化分析时,我仔细检查了本地测试,一切正常,并按预期工作
但是,当我构建Docker映像时,type和declaredType中的值都为null
我使用以下代码运行Spoon分析
private SourceCodeMetamodel buildMetamodelForFiles(Collection<File> javaFiles) {
Launcher spoonAPI = new Launcher();
log.debug("Spoon environment - {}",ToStringBuilder.reflectionToString(spoonAPI.getEnvironment()));
log.debug("Spoon model builder - {}",ToStringBuilder.reflectionToString(spoonAPI.getModelBuilder()));
Set<String> inputResources = new HashSet<>();
for (File javaFile: javaFiles) {
String javaDir = JavaFileUtils.getJavaFileStorageRootPath(javaFile);
if (StringUtils.isNotBlank(javaDir) && !inputResources.contains(javaDir)) {
spoonAPI.addInputResource(javaDir);
inputResources.add(javaDir);
}
else if (StringUtils.isBlank(javaDir)) {
spoonAPI.addInputResource(javaFile.getAbsolutePath());
}
}
spoonAPI.buildModel();
CtModel ctModel = spoonAPI.getModel();
Collection<CtType<?>> modelTypes = ctModel.getAllTypes();
return new SpoonSourceCodeMetamodel(modelTypes,false);
}
在运行Launcher之前,我试图打印它的设置。这是我得到的
2021-05-14 13:26:12.329 DEBUG 1 --- [ task-1] c.s.s.r.i.s.SpoonJavaSourceCodeAnalyzer : Spoon environment - spoon.support.StandardEnvironment@4626a7ce[errorCount=0,processingStopped=false,prettyPrintingMode=FULLYQUALIFIED,warningCount=0,sourceClasspath=<null>,preserveLineNumbers=false,copyResources=true,enableComments=true,level=ERROR,shouldCompile=false,skipSelfChecks=false,complianceLevel=8,previewFeaturesEnabled=false,outputType=classes,noclasspath=true,compressionType=GZIP,sniperMode=false,ignoreDuplicateDeclarations=false,prettyPrinterCreator=<null>,useTabulations=false,tabulationSize=4,binaryOutputDirectory=/spooned-classes]
2021-05-14 13:26:12.333 DEBUG 1 --- [ task-1] c.s.s.r.i.s.SpoonJavaSourceCodeAnalyzer : Spoon model builder - spoon.support.compiler.jdt.JDTBasedSpoonCompiler@2df98092[environment=<null>,probs=[],requestor=spoon.support.compiler.jdt.TreeBuilderRequestor@57050733,factory=spoon.reflect.factory.FactoryImpl@237d7ffa,javaCompliance=7,sources=<virtual folder>: spoon.support.compiler.VirtualFolder@42618617,templates=<virtual folder>: spoon.support.compiler.VirtualFolder@7fb32ea2,templateClasspath={},compilationUnitFilters=[],sortList=true]
我正在两种环境中运行Java8上的项目(详细信息如下)。 要构建docker,我使用以下命令
FROM java:8
COPY maven /maven/
ENTRYPOINT java -Xverify:none -XX:TieredStopAtLevel=1 -XX:+TieredCompilation -XX:+UseSerialGC -XX:MinHeapFreeRatio=20 -XX:MaxHeapFreeRatio=40 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=${PROFILE:-docker-dev} -jar /maven/skillcounters-sca-service-1.0-SNAPSHOT.jar
我试图切换到不同的Docker基本映像(openjdk\alpine等),但没有任何帮助。 我试图排除上面列出的所有java运行选项(例如-XXblabla)——也没有任何帮助
为了了解可能出现的问题,我在应用程序启动时打印所有环境(包括java)数据
这里是为本地环境打印的内容
Apple_PubSub_Socket_Render : /private/tmp/com.apple.launchd.xCrhs0tTMM/Render
COMMAND_MODE : unix2003
HOME : /Users/sk
JAVA_MAIN_CLASS_66239 : org.codehaus.classworlds.Launcher
JAVA_MAIN_CLASS_66249 : com.skillcounters.sca.SCAServiceApplication
LANG : ru_RU.UTF-8
LC_CTYPE : ru_RU.UTF-8
LOGNAME : sk
PATH : /Users/sk/Develop/d20/db/liquibase:/Users/sk/anaconda/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PID : 66249
PWD : /Users/sk/Develop/d20/d20-git-repo/skillcounters-sca-service/skillcounters-sca-service-impl
SECURITYSESSIONID : 186a9
SHELL : /bin/bash
SSH_AUTH_SOCK : /private/tmp/com.apple.launchd.ItaWSltKcA/Listeners
TMPDIR : /var/folders/lz/gjd4j2t12_39qs0hpdjqd3sh0000gn/T/
USER : sk
XPC_FLAGS : 0x0
XPC_SERVICE_NAME : com.apple.xpc.launchd.oneshot.0x10000002.idea
__CF_USER_TEXT_ENCODING : 0x1F5:0x0:0x0
awt.toolkit : sun.lwawt.macosx.LWCToolkit
file.encoding : UTF-8
file.encoding.pkg : sun.io
file.separator : /
ftp.nonProxyHosts : local|*.local|169.254/16|*.169.254/16
gopherProxySet : false
http.nonProxyHosts : local|*.local|169.254/16|*.169.254/16
java.awt.graphicsenv : sun.awt.CGraphicsEnvironment
java.awt.headless : true
java.awt.printerjob : sun.lwawt.macosx.CPrinterJob
java.class.path : {all dependent jars go here - excluded them not to pollute issue...}
java.class.version : 52.0
java.endorsed.dirs : /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/endorsed
java.ext.dirs : /Users/sk/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
java.home : /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre
java.io.tmpdir : /var/folders/lz/gjd4j2t12_39qs0hpdjqd3sh0000gn/T/
java.library.path : /Users/sk/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
java.runtime.name : Java(TM) SE Runtime Environment
java.runtime.version : 1.8.0_131-b11
java.specification.name : Java Platform API Specification
java.specification.vendor : Oracle Corporation
java.specification.version : 1.8
java.vendor : Oracle Corporation
java.vendor.url : http://java.oracle.com/
java.vendor.url.bug : http://bugreport.sun.com/bugreport/
java.version : 1.8.0_131
java.vm.info : mixed mode
java.vm.name : Java HotSpot(TM) 64-Bit Server VM
java.vm.specification.name : Java Virtual Machine Specification
java.vm.specification.vendor : Oracle Corporation
java.vm.specification.version : 1.8
java.vm.vendor : Oracle Corporation
java.vm.version : 25.131-b11
下面是在Docker环境中打印的内容
CA_CERTIFICATES_JAVA_VERSION : 20140324
HOME : /root
HOSTNAME : e297584466e8
JAVA_DEBIAN_VERSION : 8u111-b14-2~bpo8+1
JAVA_HOME : /usr/lib/jvm/java-8-openjdk-amd64
JAVA_VERSION : 8u111
LANG : C.UTF-8
PATH : /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PID : 8
PROFILE : prod
PWD : /
awt.toolkit : sun.awt.X11.XToolkit
file.encoding : UTF-8
file.encoding.pkg : sun.io
file.separator : /
java.awt.graphicsenv : sun.awt.X11GraphicsEnvironment
java.awt.headless : true
java.awt.printerjob : sun.print.PSPrinterJob
java.class.path : /maven/skillcounters-skill-service-1.0-SNAPSHOT.jar
java.class.version : 52.0
java.endorsed.dirs : /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/endorsed
java.ext.dirs : /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext
java.home : /usr/lib/jvm/java-8-openjdk-amd64/jre
java.io.tmpdir : /tmp
java.library.path : /usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
java.protocol.handler.pkgs : org.springframework.boot.loader
java.runtime.name : OpenJDK Runtime Environment
java.runtime.version : 1.8.0_111-8u111-b14-2~bpo8+1-b14
java.security.egd : file:/dev/./urandom
java.specification.name : Java Platform API Specification
java.specification.vendor : Oracle Corporation
java.specification.version : 1.8
java.vendor : Oracle Corporation
java.vendor.url : http://java.oracle.com/
java.vendor.url.bug : http://bugreport.sun.com/bugreport/
java.version : 1.8.0_111
java.vm.info : mixed mode
java.vm.name : OpenJDK 64-Bit Server VM
java.vm.specification.name : Java Virtual Machine Specification
java.vm.specification.vendor : Oracle Corporation
java.vm.specification.version : 1.8
java.vm.vendor : Oracle Corporation
java.vm.version : 25.111-b14
任何帮助都将不胜感激
# 1 楼答案
当我将Spoon Launcher日志设置为“ALL”时,我发现了一些线索
这是我在Docker环境中得到的
在本地环境中,这些警告不会显示
有一些类路径问题类似于https://www.programmersought.com/article/47106442813/
经过将近一天的努力,我找到了一个解决办法