Google App Engine Enhancer fails - missing JAR in CLASSPATH
Hello,
(question at the end, after the project configuration)
I created a MAVEN Google App Engine project with several sub-modules:
- WAR: this packages the App for uploading to GAE / running locally in dev server
- main JARs: just a couple of jars with business logic
- persistence layer JAR: this is the JAR that includes our JPA2 (Datanucleus) infrastructure layer
Using the MAVEN project all works fine, I mean, running "mvn package" in project (3) does what it is expected (compile, enhance, etc etc), and running "mvn package" in project (1) works well too (packages all dependencies from (2) and (3), etc.. Thus, running GAE dev server locally from the package generated from project (1) POM works without a problem (I can persist entities, load them, etc).
Now, I want to avoid the overhead of running "mvn install" in project (1) everytime I make a change in my code. So, I created a "run configuration" for GAE:
And this is the artifact definition:
I added all dependencies output to the WAR-exploded, so that I get all I need in the target folder (similar to a "mvn package" in the WAR project + explode).
Now, the sub-module "core-infra-jpa" has to be enhanced, so the configuration for that module is:
So, i I'm not wrong, the run configuration will:
- Make all project sub-modules
- In the case of core-infra-jpa, enhance after make
- Generate WAR-exploded: copy al target folders to WAR-target-folder (this includes classes enhanced from (2))
- Run GAE dev server
My problem, the enhance step fails:
Google AppEngine Enhancer: Encountered a problem: Unexpected exception
Google AppEngine Enhancer: mar 12, 2014 10:15:22 AM org.datanucleus.api.ApiAdapterFactory getApiAdapter
Google AppEngine Enhancer: Grave: Error : Un error ocurrio cuando creando un adaptador "org.datanucleus.api.jpa.JPAAdapter" (quizas no tengas el jar apropiado datanucleus-api-XXX en el CLASSPATH, o el api jar para la especificacion que utilisas?) : Absent Code attribute in method that is not native or abstract in class file javax/persistence/PersistenceException
Google AppEngine Enhancer: java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/persistence/PersistenceException
Google AppEngine Enhancer: at java.lang.ClassLoader.defineClass1(Native Method)
The problem is that the enhancer process needs some JARs in the classpath, this is how I got it working in MAVEN (you can see how I added dependencies to be used when running the enhacenment step):
...
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>3.1.3</version>
<configuration>
<persistenceUnitName>default</persistenceUnitName>
<api>JPA</api>
<fork>false</fork>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.google.appengine.orm</groupId>
<artifactId>datanucleus-appengine</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-enhancer</artifactId>
<version>3.1.1</version>
</dependency>
</dependencies>
</plugin>
...
So, finally, my question: how can I add those dependencies to JAVA CLASSPATH for the IntelliJ/GAE enhancer process?
Please sign in to leave a comment.
Hello,
looks strange, libraries from the modules dependencies should be included to the classpath of AppEngine Enhancer. Please enable debug logging in
build-log.xml (see https://intellij-support.jetbrains.com/entries/23352446 for details), reproduce the problem and attach build.log file.
--
Nikolay Chashnikov
JetBrains
http://www.jetbrains.com
"Develop with pleasure!"
Here it is:
2014-03-13 15:01:23,018 [ 3220] DEBUG - ncement.EnhancerProcessHandler - /Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/bin/java -Xmx256m -classpath "/Applications/IntelliJ IDEA 13.app/lib/idea_rt.jar" com.intellij.rt.execution.CommandLineWrapper /Users/javier/Library/Caches/IntelliJIdea13/compile-server/_temp_/classpath257716431150076183.tmp com.intellij.appengine.rt.EnhancerRunner /Users/javier/Library/Caches/IntelliJIdea13/compile-server/_temp_/appEngineEnhanceFiles1258433388502556888.txt com.google.appengine.tools.enhancer.Enhance -api JPA -enhancerVersion v2 -v
I can't attach you the classpath-tmp-file... it seems to be deleted just after running the command-line-wrapper.
Is datanucleus-api-jpa library shown in 'Dependencies' tab of the module editor in File | 'Project Structure' dialog? Does it help if you move the
corresponding 'dependency' tag from 'maven-datanucleus-plugin' to 'dependencies' tag in 'project' in 'pom.xml'?
--
Nikolay Chashnikov
JetBrains
http://www.jetbrains.com
"Develop with pleasure!"
Thanks for your support Nikolay,
The dependency appears in the module dependencies (intellij project created by importing a maven project):
And it is already both in 'plugins' and 'dependencies'... but the latter inside a profile in the pom:
<profiles>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Google Datastore -->
<profile>
<id>datastore</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<!-- We use resource filtering to use different XML config files in this profile -->
<build>
<resources>
<resource>
<directory>${basedir}/src/main/profiles/datastore/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.datanucleus</groupId>
<artifactId>maven-datanucleus-plugin</artifactId>
<version>3.1.3</version>
<configuration>
<persistenceUnitName>default</persistenceUnitName>
<api>JPA</api>
<fork>false</fork>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.google.appengine.orm</groupId>
<artifactId>datanucleus-appengine</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-enhancer</artifactId>
<version>3.1.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.appengine.orm</groupId>
<artifactId>datanucleus-appengine</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-api-jpa</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>javax.jdo</groupId>
<artifactId>jdo-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-core</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.datanucleus</groupId>
<artifactId>datanucleus-enhancer</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jpa_2.0_spec</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</profile>
By the way, I moved the dependencies to outside the profile to the main 'dependencies' tag but it didn't worked neither.
Is there any way to see the classpath the enhancer uses? How is that classpath temporary file created?