再会。
我在我的 Java 项目中使用 Spoon 分析库时遇到了非常奇怪的问题。运行相同的代码时,我得到不同的解析结果,在不同的环境中使用 Spoon Launcher
- 1 环境 - 从 Intellij IDEA 在本地运行的 Spring Boot 项目
- 2 环境 - 在 Docker 容器中运行的相同 Spring Boot 项目
在本地运行的 Spring Boot 项目中 - 一切正常,但是当我在 Docker 中运行相同的代码时 - 我null
在CtExecutableReference.getType()
和CtExecutableReference.getDeclaredType()
我在 GitHub 上打开了问题 - https://github.com/INRIA/spoon/issues/3926
这是详细信息
我的 Spoon 版本是 8.2.0。(来自Maven回购)
我正在尝试从这个 GitHub 存储库解析(构建 AST)代码 并且我在解析这个类时遇到了麻烦 这里有以下几行
...
@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;
}
...
}
当我运行分析并尝试解析语句方法时,我会CtExecutableReference
在findAll()
Docker中运行我的项目时获取值。在本地运行并且 具有非空值时this.valuesRepository.findAll().forEach(values::add)
null
getType()
getDeclaredType()
getType()
getDeclaredType()
解析其他项目中的其他类似代码块时会发生同样的问题。例如这里
@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;
}
}
this.betRepository.findAll()
带有null 的语句在 Docker 中运行时都为空,但在本地环境中正常getType
。getDeclaredType
同时以下代码在两种环境中都能很好地解析
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()
解析正常,并且在 Docker 和 n 本地 Spring Boot 运行中都有必要的类型信息。
我仔细检查了本地测试 - 一切正常 - 当从 IDE 运行测试中的代码或从 IDE 启动 Spring Boot 项目并通过从 Web UI 调用服务来初始化分析时 - 它正常并且按预期工作。
但是当我构建 Docker 映像时 - 我的类型和声明类型都为空。
我正在使用以下代码运行 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
任何帮助,将不胜感激