我需要在Eclipse项目中配置哪些内容才能修复“无法解析导入的XXX”错误?

9

我正在跟随这个CXF使用契约优先教程。

一切都进行得很顺利,包括从WSDL生成源代码,使用build-helper-maven-plugin,但当到达“实现服务”的时候,即将生成的RegistryResourceImpl.java移动到正常的源代码文件夹src/main/java时,Eclipse开始抱怨一些符号(如接口RegistryResource)未被识别。

意识到正常的src/main/java文件夹被分配了不同的包名,我只需在RegistryResourceImpl.java中添加导入RegistryResource.java所属的包的语句:

import com.yourcompany.sample.ns.RegistryResource;

但是,当前项目配置下的Eclipse似乎无法识别com.yourcompany.sample.ns,不知道该从哪里找到它。
我尝试在构建路径中寻找选项来指向生成的源代码,但是我尝试的所有方法都没有帮助。
我觉得我可能错过了一些非常琐碎的东西,但是它是什么?
此外,m2e(适用于Eclipse的Maven插件)难道不应该自动处理这种移动实现文件的情况吗?
更新(尝试@Patrick建议的解决方案后):
  1. target/generated/src/main/java文件夹不存在,但勾选"创建新文件夹"后,我成功创建了它。
  2. 然而,在pom.xml > Run As > Maven clean之后,它会被删除(所以每次都需要重新创建???)
  3. 如果不在clean之后重新创建,那么在pom.xml > Run As > Maven install中,生成的源代码将被创建在一个完全不同的路径下:generated-sources/cxf/com/yourcompany/sample/ns。为什么???
  4. 然而,RegistryResourceImpl.java模块仍然自动创建在target/generated sources下。此时,我不再看到关于"未解析的包/导入/符号"的投诉(奇怪)。
  5. 但是...一旦它被移动到非target文件夹/包中,即com.yourcompany.sample.ns在src/main/java下,"import com.yourcompany.sample.ns.RegistryType;"再次无法解析!
另一方面,如果我尝试将实际生成的路径 generated-sources/cxf/com/yourcompany/sample/ns 添加为“源文件夹”(而不是不存在的 target/generated/src/main/java),则在 target 下生成的树会被移动(删除)到 /src/main/java 下。我不理解 Eclipse 的这种行为。
最后,即使我按照 此处 建议执行 Maven > 更新项目,从而摆脱“Maven 2 项目错误图标”,RegistryResourceImpl.java 模块仍然显示未解析的符号,尽管整个项目构建完全正常! 这是什么原因呢? build-helper-maven-plugin 可能不完整或甚至损坏了吗?
是否有一种方法可以使 CXF + build-helper-maven-plugin 与 Eclipse 和谐工作,以便即使项目成功构建,也不会看到那些令人不安的“未解析符号”的红色下划线?

你的工作区中所有项目都编译通过了吗?因为有时依赖项目会出错。如果你提到的导入是一个jar包,请检查你是否有多个版本,正在使用哪个版本。 - Sachin Thapa
4个回答

7
您需要在Eclipse中添加一个源文件夹来存储您生成的源代码。教程在评论中提到了这一点:“注意:M2Eclipse似乎无法捕捉到这个源文件夹,因此您需要在Eclipse中手动添加它。”如果您按照教程中的说明操作,您需要添加的位置应该是(相对于您的项目目录)。
target/generated/src/main/java

要添加文件夹,请打开项目属性并从左侧菜单中选择“Java Build Path”。在“Source”选项卡中,点击“Add Folder…”按钮,然后选择“target/generated/src/main/java”作为源文件夹。
请注意,当运行 mvn clean install 时,Maven会删除生成的文件夹。您可能希望配置Eclipse在运行此命令时刷新资源,以避免不一致。Eclipse运行配置包括一个“Refresh”选项卡,可让您在完成后启用“刷新资源”。
您可以考虑的另一个选项是跳过在wsimport中使用Maven的需求。我会直接调用wsimport,将生成的工件放在您的 src / main / java 文件夹下,并完成它。除非您确实需要在每次构建时重新生成工件,否则我认为Maven插件比其价值更高。

你的回答让我更接近解决问题,但请看我的更新,如果您能解释为什么构建系统(即Eclipse + CXF + Maven)表现得如此奇怪,我将不胜感激。谢谢+1。 - Eternal Learner
我在我的回答中添加了更多细节。如果有帮助,请告诉我。 - Patrick
通常认为在src/main/java中添加生成的类是一种不好的做法。最好将它们生成在target目录下,并使用build-helper-maven-plugin将其添加到构建路径中,例如如果没有连接器的话。 - JSamir

3
如果在清理后不重新创建,执行pom.xml > Run As > Maven install,则会在完全不同的树下创建生成的源代码:generated-sources/cxf/com/yourcompany/sample/ns。为什么??
您需要配置cxf-codegen-plugin以将生成的代码输出到所需的文件夹中。
...
<configuration>
    <sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
    ...  
</configuration>  

然后,安装cxf-codegen-plugin的连接器(如果有的话),或者使用maven的build-helper-maven-plugin及其连接器。确保sources指向与sourceRoot相同的位置。

<configuration>
    <sources>
        <source>${basedir}/target/generated/src/main/java</source>
    </sources>
</configuration>

提示:要安装/发现连接器,请转到首选项 -> Maven -> 发现


2
这似乎是到目前为止关于如何更改生成源路径的最佳提示。看起来我需要在每个Maven插件中都做一个博士学位...是否有一个中央参考可以提供从A到Z的配方,以正确配置具有各种特异性和要求的Maven项目? - Eternal Learner

0
问题在于生成的源文件夹中有许多其他类定义,这些类定义也是RegistryResourceImpl类所需的。您需要将生成的源文件夹添加为Maven pom中的源代码位置。类似的问题有一个不错的答案
从那个答案中适当地引用:
 <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>add-source</id>
            <phase>generate-sources</phase>
            <goals>
                <goal>add-source</goal>
            </goals>
            <configuration>
                <sources>
                    <source>${project.build.directory}/generated-sources/java/</source>
                </sources>
            </configuration>
        </execution>
    </executions>
 </plugin>

3
谢谢。我已经做过那个了。那不是问题的根源。问题出现在生成源代码之后,只有当我尝试将其中一个移动到不同的源/包路径时才会出现。有什么建议吗? - Eternal Learner

0

您确定要在每次构建时生成这些源码吗?从外观上看,cxf-codegen-plugin中的generate-sources仅生成存根文件,然后您必须修改它们(即您提到的“实现服务”部分)才能完全完成文件。在这种情况下,您无论如何都不希望generate-sources覆盖您的文件每次构建,对吧?这应该是您必须明确调用的内容(一个Maven profile可能是一个不错的选择;或者可能是一些触发wsdl文件编辑的东西)。然后,您可以在明确请求时生成到目标或某个任意(非源)目录,并将这些文件拉取/合并到标准的src/main/java部分。如果文件已经完整生成,那么情况就不同了,但由于您需要先生成然后编辑然后完全构建,所以这不是一个一次性的操作...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接