GWT + Appengine + JPA + Eclipse + Maven:如何让他们一起工作

时间:2013-04-16 14:16:52

标签: google-app-engine maven gwt jpa google-plugin-eclipse

我有一个项目,我想使用eclipse GWT工具(开发模式和调试器)与我正在编写的GWT / Appengine / Maven应用程序进行交互。我的东西处于有些有效的状态,但仍然有一些我无法正确处理的事情。如果有人能帮我解决这些问题,我会发布POM文件。

  • 当我执行Maven->更新项目时,我放弃了eclipse项目属性中的appengine性质,并且必须转到Properties,Google,AppEngine并重新检查使用Google App Engine。我可以在POM中做些什么我不放松的发源性质?我正在使用Google appengine-maven-plugin插件。这似乎是官方使用的。
  • 在maven构建之后,我必须执行一个项目清理以使jpa类得到增强,然后才能使用Run As - Web Application启动器运行它们。 maven构建包含在构建中工作的域对象的测试用例 - 我在构建'maven-datanucleus-plugin:3.1.3:enhance(default)'中看到了这个目标正在增强的类。但是作为一个Web应用程序运行它会抛出错误告诉我类没有增强,除非我做一个项目清理,导致eclipse做它的增强。有没有办法避免这个额外的步骤?
  • 我无法运行JUnit View测试运行器或使用使用该视图的启动器。 JUnit View抱怨:“引起:org.datanucleus.exceptions.NucleusException:插件(Bundle)”org.datanucleus“已经注册。确保在类路径中没有相同插件的多个JAR版本.URL”文件:/ C:/Users/bondsd/.m2/repository/org/datanucleus/datanucleus-core/3.1.3/datanucleus-core-3.1.3.jar“已经注册,您正在尝试注册一个相同的插件在URL“file:/ C:/Program%20Files/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.7.5/appengine-java-sdk-1.7.5/lib/opt/user/datanucleus/v2/datanucleus -core-3.1.3.jar。 “”。我尝试了各种各样的事情,例如删除datanucleus插件和/或依赖项,各种配置选项,以及在app引擎属性面板中取消选中“使用Datnucleus JDO / JPA访问数据存储区”。有没有办法让这个工作?

以下是我与公司使用的POM和项目名称x'ed out。如果你需要发射器,我也很乐意发布它们。提前感谢您的任何建议或帮助。我已经搜索过互联网,但尚未找到合适的解决方案。

<modelVersion>4.0.0</modelVersion>

<groupId>com.xxx.xxxx</groupId>
<artifactId>shell</artifactId>
<packaging>war</packaging>
<version>0.1.0-proto</version>

<name>XXXXXX</name>
<description>A XXXXXXXX</description>

<properties>
    <webappDirectory>${project.build.directory}/${project.build.finalName}</webappDirectory>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- GWT version -->
    <gwt.version>2.5.1</gwt.version>
    <gwt.style>PRETTY</gwt.style>

    <!-- GAE version -->
    <appengine.version>1.7.6</appengine.version>
    <appengine.sdk.version>1.7.6</appengine.sdk.version>
    <appengine.orm.version>2.1.2</appengine.orm.version>
    <appengine.port>8888</appengine.port>
    <datanucleus.core.version>3.1.3</datanucleus.core.version>
    <datanucleus.api.version>3.1.3</datanucleus.api.version>
    <datanucleus.enhancer.version>3.1.1</datanucleus.enhancer.version>
    <datanucleus.plugin.version>3.1.3</datanucleus.plugin.version>

    <slf4jVersion>1.6.6</slf4jVersion>
    <log4j.version>1.3</log4j.version>
    <junit.version>4.11</junit.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.google.gwt.inject</groupId>
        <artifactId>gin</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>com.google.inject.extensions</groupId>
        <artifactId>guice-servlet</artifactId>
        <version>3.0</version>
    </dependency>

    <!-- GWT dependencies -->
    <dependency>
        <groupId>com.google.gwt</groupId>
        <artifactId>gwt-servlet</artifactId>
        <version>${gwt.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.google.gwt</groupId>
        <artifactId>gwt-user</artifactId>
        <version>${gwt.version}</version>
        <scope>provided</scope>
    </dependency>



    <!-- GAE SDK -->
    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-api-1.0-sdk</artifactId>
        <version>${appengine.version}</version>
    </dependency>

    <!-- For the servlet filter -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
    <!-- <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> 
        <version>1.2</version> </dependency> -->


    <!-- RequestFactory server -->
    <dependency>
        <groupId>com.trycatchsoft.gwt.requestfactory</groupId>
        <artifactId>injected-requestfactory</artifactId>
        <version>1.2.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.google.web.bindery</groupId>
        <artifactId>requestfactory-server</artifactId>
        <version>${gwt.version}</version>
    </dependency>
    <dependency>
        <groupId>com.google.web.bindery</groupId>
        <artifactId>requestfactory-apt</artifactId>
        <version>${gwt.version}</version>
    </dependency>


    <!-- RequestFactory will use JSR 303 javax.validation -->

    <!-- Validation API -->
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.0.0.GA</version>
    </dependency>

    <!-- Validation Implementation -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.0.Final</version>
    </dependency>


    <!--Test Dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-all</artifactId>
        <version>1.9.0</version>
        <scope>test</scope>
    </dependency>
    <!-- GAE libraries for local testing as described here: http://code.google.com/appengine/docs/java/howto/unittesting.html -->
    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-api-labs</artifactId>
        <version>${appengine.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-api-stubs</artifactId>
        <version>${appengine.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.google.appengine</groupId>
        <artifactId>appengine-testing</artifactId>
        <version>${appengine.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- End of Test Dependencies -->

    <!-- JPA 2.0 for GAE -->
    <dependency>
        <groupId>com.google.appengine.orm</groupId>
        <artifactId>datanucleus-appengine</artifactId>
        <version>${appengine.orm.version}</version>
    </dependency>
    <!-- Datanucleus -->
    <!-- datanucleus-core is not needed for compilation. in fact, it cannot 
        have compile scope because the datanucleus plugin automatically adds it during 
        enhancement and complains if there are two copies. app should not depend 
        on any classes in this lib anyways. -->
    <dependency>
        <groupId>org.datanucleus</groupId>
        <artifactId>datanucleus-core</artifactId>
        <version>${datanucleus.core.version}</version>
        <scope>runtime</scope>
        <exclusions>
            <exclusion>
                <groupId>javax.transaction</groupId>
                <artifactId>transaction-api</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- datanucleus-jpa is needed during compilation for its @Extension annotation 
        which is used throughout entity classes -->
    <dependency>
        <groupId>org.datanucleus</groupId>
        <artifactId>datanucleus-api-jpa</artifactId>
        <version>${datanucleus.api.version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.geronimo.specs</groupId>
        <artifactId>geronimo-jpa_2.0_spec</artifactId>
        <version>1.0</version>
    </dependency>

    <dependency>
        <groupId>org.eclipse.persistence</groupId>
        <artifactId>javax.persistence</artifactId>
        <version>2.0.0</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.7.2</version>
    </dependency>
    <!-- SLF4J logging libraries -->
    <!-- <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> 
        <version>${slf4jVersion}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> 
        <artifactId>slf4j-log4j12</artifactId> <version>1.7.2</version> </dependency> 
        <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.16</version> 
        </dependency> -->

    <!-- End SLF4J logging libraries -->
</dependencies>




<build>
    <!-- Generate compiled stuff in the folder used for developing mode -->
    <outputDirectory>${webappDirectory}/WEB-INF/classes</outputDirectory>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>

    <plugins>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.0</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
            <dependencies>
                <!-- Need to run the RF Validation tool. This works on both the command-line 
                    and in Eclipse, provided that m2e-apt is installed. -->
                <dependency>
                    <groupId>com.google.web.bindery</groupId>
                    <artifactId>requestfactory-apt</artifactId>
                    <version>${gwt.version}</version>
                </dependency>
            </dependencies>
        </plugin>


        <!-- GWT Maven Plugin -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>gwt-maven-plugin</artifactId>
            <version>2.5.1-rc1</version>
            <dependencies>
                <!-- Force plugin to use same gwt version -->
                <dependency>
                    <groupId>com.google.gwt</groupId>
                    <artifactId>gwt-user</artifactId>
                    <version>${gwt.version}</version>
                </dependency>
                <dependency>
                    <groupId>com.google.gwt</groupId>
                    <artifactId>gwt-dev</artifactId>
                    <version>${gwt.version}</version>
                </dependency>
            </dependencies>
            <configuration>
                <strict>true</strict>
                <extraJvmArgs>-Xss1024K -Xmx1024M -XX:MaxPermSize=256M</extraJvmArgs>
                <logLevel>INFO</logLevel>
                <style>${gwt.style}</style>
                <copyWebapp>true</copyWebapp>
                <hostedWebapp>${webappDirectory}</hostedWebapp>
                <runTarget>Shell.html</runTarget>
                <webappDirectory>${webappDirectory}</webappDirectory>
                <module>com.ihg.dashboard.Shell</module>
                <server>com.google.appengine.tools.development.gwt.AppEngineLauncher</server>
                <i18nMessagesBundle>com.ihg.dashboard.client.Messages</i18nMessagesBundle>
                <appEngineVersion>${appengine.version}</appEngineVersion>
                <!-- Should GWT create the Story of Your Compile Report -->
                <compileReport>false</compileReport>
            </configuration>                
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test</goal>
                        <goal>i18n</goal>
                    </goals>
                </execution>
            </executions>

        </plugin>

        <plugin>
            <groupId>com.google.appengine</groupId>
            <artifactId>appengine-maven-plugin</artifactId>
            <version>${appengine.version}</version>
            <configuration>
                <jvmFlags>
                    <jvmFlag>-Ddatastore.backing_store=${project.basedir}\local_db.bin</jvmFlag>
                </jvmFlags>
                <enhancerApi>JPA</enhancerApi>
            </configuration>
        </plugin>


        <!-- This plug-in "enhances" your domain model objects (i.e. makes them 
            persistent for datanucleus) -->
            <!--  Might not need this, appengine is supposed to do this appengine:enhance -->
        <plugin>
            <groupId>org.datanucleus</groupId>
            <artifactId>maven-datanucleus-plugin</artifactId>
            <version>${datanucleus.plugin.version}</version>
            <configuration>
                <mappingIncludes>**/domain/*.class</mappingIncludes>
                <metadataIncludes>**/domain/*.class</metadataIncludes>
                <verbose>false</verbose>
                <enhancerName>ASM</enhancerName>
                <api>JPA</api>
            </configuration>
            <executions>
                <execution>
                    <phase>process-classes</phase>
                    <goals>
                        <goal>enhance</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <!-- enhancement requires the gwt-user jar because many of the entity 
                        classes implement IsSerializable and the enhancer needs it on the classpath 
                        to function. because the gwt-user library has a scope of provided, it is 
                        only available on the compilation and test classpath, and is not transitive 
                        to the enhancement classpath. -->
                    <groupId>com.google.gwt</groupId>
                    <artifactId>gwt-user</artifactId>
                    <version>${gwt.version}</version>
                </dependency>
                <dependency>
                    <!-- force maven-datanucleus-plugin to use the same version of datanucleus-core -->
                    <groupId>org.datanucleus</groupId>
                    <artifactId>datanucleus-core</artifactId>
                    <version>${datanucleus.core.version}</version>
                </dependency>
            </dependencies>
        </plugin>




        <!-- Copy static web files before executing gwt:run -->
        <!--  May not need this now -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>exploded</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <webXml>${webappDirectory}/WEB-INF/web.xml</webXml>
                <webappDirectory>${webappDirectory}</webappDirectory>
            </configuration>
        </plugin>

    </plugins>



    <pluginManagement>
        <plugins>
            <!--This plugin's configuration is used to store Eclipse m2e settings 
                only. It has no influence on the Maven build itself. -->
            <plugin>
                <groupId>org.eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <lifecycleMappingMetadata>
                        <pluginExecutions>
                            <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>org.codehaus.mojo</groupId>
                                    <artifactId>
                                        gwt-maven-plugin
                                    </artifactId>
                                    <versionRange>
                                        [2.5.1-rc1,)
                                    </versionRange>
                                    <goals>
                                        <goal>i18n</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <ignore></ignore>
                                </action>
                            </pluginExecution>
                            <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>
                                        org.datanucleus
                                    </groupId>
                                    <artifactId>
                                        maven-datanucleus-plugin
                                    </artifactId>
                                    <versionRange>
                                        ${datanucleusVersion}
                                    </versionRange>
                                    <goals>
                                        <goal>enhance</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <execute />
                                </action>
                            </pluginExecution>
                        </pluginExecutions>
                    </lifecycleMappingMetadata>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>
</build>

======================================= < / p>

On Edit:以下是项目符号点3的解决方案。在Project Properties - Google - App Engine页面中禁用JPA / JDO。转到构建路径并删除列为顶级库的所有datanucleus库(通过在项目属性中启用appengine将它们放在那里)。确保Maven依赖项位于Order选项卡列表的底部。

编辑2:我在Maven-&gt;更新项目时找到了保持GAE项目性质的方法。我把它添加到POM中(即使我使用的是安装了m2e的eclipse构建)

            <plugin>
            <artifactId>maven-eclipse-plugin</artifactId>
            <version>2.7</version>
            <configuration>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>false</downloadJavadocs>
                <wtpversion>2.0</wtpversion>
                <additionalBuildcommands>
                    <buildCommand>
                        <name>com.google.gwt.eclipse.core.gwtProjectValidator</name>
                    </buildCommand>
                </additionalBuildcommands>
                <additionalProjectnatures>
                    <projectnature>com.google.gwt.eclipse.core.gwtNature</projectnature>
                    <projectnature>com.google.appengine.eclipse.core.gaeNature</projectnature>
                </additionalProjectnatures>
            </configuration>
        </plugin>

这解决了Bullet点1.所以现在我解决了第1点和第3点(种类)。我仍然需要一种方法来解决第2点问题,尽管如果我记得要做的话,解决方法很容易。我更担心那些在我记住之后得到代码的人。

我也在寻找一种不使用eclipse启动器的方法。我知道可以通过添加各种配置文件和配置来完成。我只需要找到合适的配置来做到这一点。通过这个,我的意思是一个配置文件,它将以开发模式(或超级开发模式)运行gwt代码,还有一个配置文件,它将在开发模式下运行带有gwt代码的调试器。


在编辑3 :我解决了要点2.这就像关闭Project-&gt; Build Automatically一样简单。我不确定那首先是什么。

这就解决了所有3个要点。在这一点上,我可能应该为这个问题创建一个答案,并为那些对此感兴趣并且没有读到这一点的人解决它。我会在一两天内做到这一点(当我有时间撰写一个很好的答案时)。

1 个答案:

答案 0 :(得分:1)

看起来你的maven设置很好,但是让我做一些可能有帮助的观察。

1)我会从appengine-maven-plugin中删除enhancerApi,因为我们只是执行与maven-datanucleus-plugin相同的事情。因此,不要运行appengine:增强目标以及datanucleus插件的目标。

2)datanucleus插件只是为了增强域类而设置,这对我来说是正确的,但我猜测就是这样。

3)我不再是eclipse的最佳选择了,但我很好奇你正在使用哪个maven插件,m2eclipse插件是由sonatype开发的,在我看来是最准确的。

4)在编译时执行war插件对我来说似乎不对,因为这应该默认为包阶段,这可以确保其他阶段事先正确执行。

5)您可能需要为插件设置更多的执行指令,或者如果它们存在则依赖于默认值。 maven生命周期可能有点棘手,我建议您阅读http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html并确保在启动应用程序之前eclipse正在运行正确的阶段。