I am going to create a project template using gradle. The following has been tested against Eclipse 4.3 (Kelper), Gradle 1.10 and Google App Engine SDK 1.8.9. It is also assumed that the Google GAE plugin has been installed in Eclipse. With this project template one should be able to:
-
Build a war file by running
gradle war
- Create an eclipse project with Google App Engine (GAE) nature by running
gradle cleanEclipse eclipse
1. Apply the plugins
In build.gradle, firstly we need to add the required plugins:
apply plugin: 'war' apply plugin: 'eclipse-wtp' apply plugin: 'gae'The eclipse-wtp is added as the Eclipse GAE plugin will create an GAE project as web project, so I generate an eclipse web project too.
2. Copy artifacts from local App Engine SDK folder
Originally I want to pull the GAE artifacts from google repositories, just like other 3rd party maven dependencies. So I configure the following maven repository:
repositories { mavenCentral() maven {url 'https://oss.sonatype.org/content/repositories/google-releases/'} }
However, eclipse will complain about the different jar size with the App Engine SDK for datanucleus-appengine-2.1.2.jar. Therefore, if there is already App Engine SDK installed locally, I would recommend to copy the artifacts from the SDK folder; otherwise, just specify the maven dependencies as usual.
In this template, I assume the SDK exists locally and an environment variable APPENGINE_HOME must be set to point to the SDK location.
The dependencies are listed as follow,
ext { springVersion = '3.2.6.RELEASE' appEngineHome = "$System.env.APPENGINE_HOME" appEngineSdkVersion = '1.8.9' } dependencies { providedCompile "javax.servlet:servlet-api:2.5" testCompile "junit:junit:4.+" compile "org.springframework:spring-webmvc:$springVersion" // AppEngine dependencies, copy from APPENGINE_HOME lib folders compile files( "$appEngineHome/lib/user/appengine-api-1.0-sdk-${appEngineSdkVersion}.jar", "$appEngineHome/lib/opt/user/appengine-api-labs/v1/appengine-api-labs.jar", "$appEngineHome/lib/opt/user/appengine-endpoints/v1/appengine-endpoints.jar", "$appEngineHome/lib/opt/user/appengine-endpoints/v1/appengine-endpoints-deps.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/asm-4.0.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/datanucleus-core-3.1.3.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/datanucleus-api-jpa-3.1.3.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/datanucleus-api-jdo-3.1.3.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/datanucleus-appengine-2.1.2.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/geronimo-jpa_2.0_spec-1.0.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/jdo-api-3.0.1.jar", "$appEngineHome/lib/opt/user/datanucleus/v2/jta-1.1.jar", "$appEngineHome/lib/opt/user/jsr107/v1/jsr107cache-1.1.jar", "$appEngineHome/lib/opt/user/jsr107/v1/appengine-jsr107cache-${appEngineSdkVersion}.jar") // runtime dependencies runtime "javax.servlet:jstl:1.1.2" }As I would like to setup Spring later, the Spring MVC dependency is added.
I would also like to populate the WEB-INF/lib folder by copying the dependencies so I do not need to check-in the jars to source control system, so I add the following:
// task to clean WEB-INF/lib folder task cleanWarLibDir(type: Delete) { delete fileTree(dir: "war/WEB-INF/lib") } // task to populate WEB-INF/lib folder from the compile dependencies task populateWarLib(type: Copy) { into('war/WEB-INF/lib') from configurations.compile } // populate the WEB-INF/lib tasks.eclipse.dependsOn('checkenv','populateWarLib') tasks.populateWarLib.dependsOn('cleanWarLibDir')
The checkenv task is just used to check the APPENGINE_HOME environment variable. If the variable is not set, it will throw an exception.
3. Setup the eclipse project configurations
The Eclipse GAE plugin is picky about the project settings. Although it is kind of web project, it does not expect the existence of web container library. Thus the jars in WEB-INF/lib will not be added to the build path automatically in Eclipse, and we need to add the needed jars as external libraries manually in eclipse IDE.
Here is the eclipse part of the gradle configuration:
eclipse { // add build commands and specify the project natures project { natures.clear() natures 'org.eclipse.jdt.core.javanature', 'com.google.appengine.eclipse.core.gaeNature', 'org.eclipse.wst.common.project.facet.core.nature' buildCommands.clear() buildCommand 'org.eclipse.wst.common.project.facet.core.builder' buildCommand 'org.eclipse.jdt.core.javabuilder' buildCommand 'com.google.gdt.eclipse.core.webAppProjectValidator' buildCommand 'com.google.appengine.eclipse.core.gaeProjectChangeNotifier' buildCommand 'com.google.appengine.eclipse.core.projectValidator' buildCommand 'com.google.appengine.eclipse.core.enhancerbuilder' } classpath { defaultOutputDir = file("${project.projectDir}/war/WEB-INF/classes") // correct classpaths as needed by GAE eclipse plugin containers.clear() containers.add 'com.google.appengine.eclipse.core.GAE_CONTAINER' containers.add 'org.eclipse.jdt.launching.JRE_CONTAINER' file { whenMerged { classpath -> classpath.entries.removeAll { entry -> entry.kind == 'lib' || (entry.kind == 'con' && entry.path == 'org.eclipse.jst.j2ee.internal.web.container') } classpath.entries.findAll { entry -> entry.hasProperty('exported') }*.exported = false } } } // GAE application needs Java 1.7 wtp { facet { facet name: 'java', version: '1.7' } } }We also need to add two google specific properties files in the .setting folder:
// fix the GAE eclipse prop file tasks.eclipse.doLast { // write settings file 'com.google.appengine.eclipse.core.prefs' ant.propertyfile(file: ".settings/com.google.appengine.eclipse.core.prefs") { ant.entry(key: "eclipse.preferences.version", value: "1") ant.entry(key: "gaeDatanucleusVersion", value: "v2") ant.entry(key: "gaeHrdEnabled", value: "true") } // write settings file 'com.google.gdt.eclipse.core.prefs' ant.propertyfile(file: ".settings/com.google.gdt.eclipse.core.prefs") { ant.entry(key: "eclipse.preferences.version", value: "1") ant.entry(key: "warSrcDir", value: "war") ant.entry(key: "warSrcDirIsOutput", value: "true") } }Without the above files the Eclipse GAE plugin will complain about the version of jars in WEB-INF/lib.
Okay, that's it. One should be able to import this project after running "gradle cleanEclipse eclipse". If you have already created an application in google appengine console, you should be able to deploy it in Eclipse using the GAE plugin.
Note that I also include the gradle gae plugin, so even there is no eclipse one should be able to do the deployment using gradle directly.
The project template is available on GitHub.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.