• 问题.spring源码转换为eclipse遇到的问题


    1.下载spring源码

    2.下载安装gradle,配置环境变量

    3.在spring子项目下执行命令:gradle cleanidea eclipse,会生成对应的.project及.classpath文件

    4.eclipse导入project

    第一步和第二步就没必要说了,在执行第三步的遇到一个如下问题:

    错误报告意思应该是:调用ProjectDependency的构造函数时传的参数与定义的不匹配。好在报告上说出了在哪里调用的:ide.gradle

    import org.gradle.plugins.ide.eclipse.model.ProjectDependency
    import org.gradle.plugins.ide.eclipse.model.SourceFolder
    
    
    apply plugin: "propdeps-eclipse"
    apply plugin: "propdeps-idea"
    
    eclipse.jdt {
    	sourceCompatibility = 1.8
    	targetCompatibility = 1.8
    }
    
    // Replace classpath entries with project dependencies (GRADLE-1116)
    // http://issues.gradle.org/browse/GRADLE-1116
    eclipse.classpath.file.whenMerged { classpath ->
    	def regexp = /.*?/([^/]+)/build/[^/]+/(?:main|test)/ // only match those that end in main or test (avoids removing necessary entries like build/classes/jaxb)
    	def projectOutputDependencies = classpath.entries.findAll { entry -> entry.path =~ regexp }
    	projectOutputDependencies.each { entry ->
    		def matcher = (entry.path =~ regexp)
    		if (matcher) {
    			def projectName = matcher[0][1]
    			def path = "/${projectName}"
    			if(!classpath.entries.find { e -> e instanceof ProjectDependency && e.path == path }) {
    				def dependency = new ProjectDependency(path, project(":${projectName}").path)
    				dependency.exported = true
    				classpath.entries.add(dependency)
    			}
    			classpath.entries.remove(entry)
    		}
    	}
    	classpath.entries.removeAll { entry -> (entry.path =~ /(?!.*?repack.*.jar).*?/([^/]+)/build/libs/[^/]+.jar/) }
    }
    

    在line:24看到 def dependency = new ProjectDependency(path, project(":${projectName}").path),这显然在创建对象时传入的参数与构造函数的定义不匹配,看上面import知道这个类是由gradle来定义的,所以再去确认下gradle中这个类的定义。

    需要下载gradle全量包,在src目录下可以找到对应的类源码:

     1 package org.gradle.plugins.ide.eclipse.model;
     2 
     3 import com.google.common.base.Preconditions;
     4 import groovy.util.Node;
     5 
     6 /**
     7  * A classpath entry representing a project dependency.
     8  */
     9 public class ProjectDependency extends AbstractClasspathEntry {
    10 
    11     public ProjectDependency(Node node) {
    12         super(node);
    13         assertPathIsValid();
    14     }
    15 
    16     /**
    17      * Create a dependency on another Eclipse project.
    18      * @param path The path to the Eclipse project, which is the name of the eclipse project preceded by "/".
    19      */
    20     public ProjectDependency(String path) {
    21         super(path);
    22         assertPathIsValid();
    23     }
    24 
    25     private void assertPathIsValid() {
    26         Preconditions.checkArgument(path.startsWith("/"));
    27     }
    28 
    29     @Override
    30     public String getKind() {
    31         return "src";
    32     }
    33 
    34     @Override
    35     public String toString() {
    36         return "ProjectDependency" + super.toString();
    37     }
    38 }

    可以看到,构造函数中只要传个path就可以了,看这个注释的意思应该就是传参时的那个path。

    这个时候抱着试一试的心态将脚本传的参数project(":${projectName}").path去除后,重新执行命令,然后。。。build successful。

    回顾这个问题,其实就是脚本传参不对,根据提示找到对应类的定义知道应该传什么参数。

    这地方怀疑可能是gradle更新了这个函数定义,但spring没有去更新这个脚本。或者它们用的gradle的版本与我的不一样。我本地下的是gradle-4.0

    后来发现这个坑真的是我自己挖的,在spring源码路径下有gradle脚本,打开会看到它去尝试下载gradle-3.5,然后我又下了3.5,果然........

     1 package org.gradle.plugins.ide.eclipse.model;
     2 
     3 import com.google.common.base.Preconditions;
     4 import groovy.util.Node;
     5 import org.gradle.util.DeprecationLogger;
     6 
     7 /**
     8  * A classpath entry representing a project dependency.
     9  */
    10 public class ProjectDependency extends AbstractClasspathEntry {
    11 
    12     private String gradlePath;
    13 
    14     public ProjectDependency(Node node) {
    15         super(node);
    16         assertPathIsValid();
    17     }
    18 
    19     /**
    20      * Create a dependency on another Eclipse project.
    21      * @param path The path to the Eclipse project, which is the name of the eclipse project preceded by "/".
    22      */
    23     public ProjectDependency(String path) {
    24         super(path);
    25         assertPathIsValid();
    26     }
    27 
    28     /**
    29      * Create a dependency on another Eclipse project.
    30      * @deprecated Use {@link #ProjectDependency(String)} instead
    31      */
    32     @Deprecated
    33     public ProjectDependency(String path, String gradlePath) {
    34         this(path);
    35         DeprecationLogger.nagUserOfDiscontinuedMethod("ProjectDependency(String path, String gradlePath)", "Please use ProjectDependency(String path) instead.");
    36         this.gradlePath = gradlePath;
    37     }
    38    
    39    ...
    40 }

    这里可以看到一个构造函数的定义,line:33,改好本地gradle后,直接在spring目录下执行gradle cleanidea eclipse试试,应该是success的

    但是导入之后并没有结束,会看到依然有红叉、感叹号等错误。需要编译的编译生成class文件,项目中有依赖、

    然后在编译时又遇如下一坑

    找到出错方法的定义:

    public class PropertyComparator<T> implements Comparator<T> {
     ...
     public static void sort(List<?> source, SortDefinition sortDefinition) throws BeansException {
            if (StringUtils.hasText(sortDefinition.getProperty())) {
                Collections.sort(source, new PropertyComparator<>(sortDefinition));
            }
        }
     ...
    }

    根据报错信息,这地方编译器期望的应该是sort(List<T> source, SortDefinition sortDefinition),而这个方法是static,非static的T用不进来,

    所以这地方,我直接改成了sort(List source, SortDefinition sortDefinition),将泛型去掉了,这样的话应该编译器会报一个warning,但总归能继续编译下去了。。。

    编译的话可以直接用源码路径下的批处理命令:gradlew.bat(预编译)和import-into-eclipse.bat,最后:

    过程中还会遇到各种其他坑,上面的两个坑只是作为补充

  • 相关阅读:
    JQuery_1
    CSS_1
    CSS_3
    CSS_4
    2020.10.19小记
    CSS_2
    IT茧
    亲爱的小C
    四五点钟的太阳
    有聊
  • 原文地址:https://www.cnblogs.com/shanhm1991/p/7145418.html
Copyright © 2020-2023  润新知