Add scala class to DataNucleus enhancer CLASSPATH - google-app-engine

I am writing a Google App Engine web app and wish to use Scala on the server side. I'm using Eclipse and the Google App Engine plugin. However, as soon as I add an empty Scala class source file to my project, the DataNucleus enhancer warns:
SEVERE: Class "com.my.package.UserAccount" was not found in the
CLASSPATH. Please check your specification and your CLASSPATH.
I will eventually get round to making the class persistent but I want to get rid of this error first.
So far I've added the Scala Nature, and have tried cleaning the project and also restarting Eclipse but I always get the same warning issued from the enhancer.
Any ideas on what I can do to get the enhancer to run successfully?

I've struggled away with this for the last few days. Class not found errors thrown by the datanucleus enhancer on Scala classes occur because the scala-library.jar file isn't in the classpath when the enhancer runs. I've found two solutions:
Simple but cludgy: Copy scala-library.jar to the folder in eclipse/plugins which contains the enhancer. For me this is currently: /opt/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.5.5.r36v201110112027/appengine-java-sdk-1.5.5/lib/tools/orm
Switch off the enhancer builder in your project properties and create an ant file to run it manually. You can then properly control the classpath. I really struggled to get the scala-library into the classpath so gave up and copied it into the same folder as my datanucleus jars. My ant file if anyone's interested is:
<project name="DataNucleusEnhancer" default="enhance" basedir=".">
<property name="base.dir" location="/home/steve/Projects/DNProject"/>
<property name="datanucleus.libs" location="/home/steve/Projects/Jar Libraries/datanucleusjars"/>
<property name="sdk.dir" location="/opt/eclipse/plugins/com.google.appengine.eclipse.sdkbundle_1.5.5.r36v201110112027/appengine-java-sdk-1.5.5"/>
<property name="classes.dir" location="${base.dir}/war/WEB-INF/classes/"/>
<property name="entities.dir" location="${base.dir}/war/WEB-INF/classes/packagenamehere/entities"/>
<path id="enhancer.classpath">
<fileset dir="${datanucleus.libs}" includes="*.jar" excludes="" />
<fileset dir="${sdk.dir}/lib/user" includes="*.jar" />
</path>
<target name="enhance" description="DataNucleus enhancement">
<taskdef name="datanucleusenhancer" classpathref="enhancer.classpath" classname="org.datanucleus.enhancer.tools.EnhancerTask" />
<datanucleusenhancer dir="${classes.dir}" failonerror="true" verbose="true">
<fileset dir="${entities.dir}" includes="**/*.class" />
<classpath>
<path location="${base.dir}/war/WEB-INF/classes/"/>
<path refid="enhancer.classpath"/>
</classpath>
</datanucleusenhancer>
</target>
</project>
In testing I also found the enhancer unwilling to enhance classes if I had no namespaces. I'm also concerned that I now need to manage the copy of scala-library.jar to make sure it's the same as in the scala eclipse plugin. It'd be much better if the gae plugin worked properly!

I tried the option 1 of steve's answer dropping the scala-library.jar in the eclipse plugin folder. It is still not solving yet. I then drop scala-library.jar in PROJECT/war/WEB-INF/lib/ and add it to Build Path. It works! So I undo option 1 of steve's answer by removing the scala-library.jar from the eclipse plugin folder and restart the eclipse. I try again and it still works! I am using eclipse 2.7.1, scala 2.9.1 and scala-ide 2.0.0

Related

Firebase access within GAE

It seems that the latest sdk com.google.firebase:firebase-server-sdk:3.0.0 relies on creating threads for most calls, e.g., com.google.firebase.database.FirebaseDatabase.getReference
This is a problem when using GAE since it promptly throws an Exception:
servlet java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup")
Are we suppoed to just use the JVM sdk (com.firebase:firebase-client-jvm) instead?
The instructions aren't so clear and it seems like the legacy website is the only one where we can get the secret. The new website gives us the .json file.
Has anyone had any success with using the new v3 version with GAE?
Yes. Just tested.
As with the 2.x SDKs, you can work around the threading limitation by using manual scaling.
While the Cloud guide on using Firebase with GAE is a bit outdated, the section on manual scaling should still be useful to help you through this.
More on ThreadManager here.
I was experiencing the same problem and discovered the cause in this blog thread.
When adding dependences, I had included appengine-java-sdk but overlooked appengine-api-1.0-sdk. Adding it eliminated the exception. The full dependencies block is:
dependencies {
appengineSdk 'com.google.appengine:appengine-java-sdk:1.9.48'
compile 'javax.servlet:servlet-api:2.5'
compile 'com.google.firebase:firebase-server-sdk:3.0.3'
compile 'com.google.appengine:appengine-api-1.0-sdk:1.9.48'
}
Include the JSON file in the "Resource Files" of appengine-web.xml.
Example:
<resource-files>
<include path="/**.xml" />
<exclude path="/feeds/**.xml" />
</resource-files>
See the link https://cloud.google.com/appengine/docs/java/config/appref#resource_files .
"The files that listed in the element are accessible by the application code using the filesystem. These files are stored on the application servers with the app as opposed to how static files are stored and served.".

JBoss Fuse - Relative paths for bundles

I have a camel project, where I use a java bean reference.
Inside this .java I'm reading a file which path is "src/main/resources/basic.xml"
I build the osgi-bundle with apache felix and I write the instruction:
<Include-Resource>src/main/resources</Include-Resource>
The bundle builds fine, and I also test with another maven plugin (mvn camel:run)
and everything works fine =)
Then I deploy it on my osgi container (Karaf) adding all dependencies for this OSGI, but it fails
cause is not finding basic.xml
FileNotFound /home/user/jboss-fuse-xx/instances/testCOntainer/src/main/resources/basic.xml
If I change the path on my .java like "basic.xml" the result is:
FileNotFound /home/user/jboss-fuse-xx/instances/testCOntainer/basic.xml
So the relative path is the container root path, where I deploy this bundle.
The easy way to resolve this, is to put the basic.xml in this path, I know :P, but ¿is there another way?
Is there an apache felix instruction that fix this??? so the bundle can resolve this path, no matter where is deployed
I've worked with the Import-package instruction before and works fine, but only when I 'call' this resource on a camel route, not in a java class.
Thanks for all the answers !!

Extracting .docx files with Tika in Apache Solr gives NoSuchMethod error

I have a Solr 4.0 module in my project (basically, a maven web project with all the solr dependencies). It worked pretty well, including content extraction and everything.
But, when I tested it with a .docx document, It gives me the following error:
13:50:34,468 ERROR [org.apache.solr.servlet.SolrDispatchFilter] (http--0.0.0.0-8080-9)
null:java.lang.RuntimeException: java.lang.NoSuchMethodError:
org.apache.poi.openxml4j.opc.PackagePart.getRelatedPart(Lorg/apache/poi/openxml4j/opc/PackageRelationship;)
Lorg/apache/poi/openxml4j/opc/PackagePart;
I tried to manually add the openxml4j dependency to the project. I've downloaded the sources and looked at it, the PackagePart#getRelatedPart really doesn't exist.
What is this error? How can I fix this?
Thanks in advance.
EDIT
I noticed that poi-ooxml already had those classes inside it. Cool, but I also inspected those sources, and still doesn't have the needed method in the PackagePart class.
BTW: I tried to add openxml4j version 1.0-beta.
It was a jarhell related issue.
Thanks, "jarhell related" was the clue I needed!
My project had POI jars prior to import of the Tika app jar, which includes its own POI jars. I deleted the standalone POI jars, and then Tika was able to handle DOCX Word 2013 file without error.
Now hopefully I won't run into a situation where I need both! :|

Jersey linking support with Google App Engine issue

I didn't manage to use the Jersey linking support with Google App Engine, I'm getting these exceptions when trying to access the application :
Caused by: javax.el.ELException: Could not find expression factory class
...
Caused by: java.lang.ClassNotFoundException: de.odysseus.el.ExpressionFactoryImpl
As specified in the documentation, I put this in the Jersey servlet section of the web.xml :
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.sun.jersey.server.linking.LinkFilter</param-value>
</init-param>
I also add the jersey-server-linking-1.13.jar to the WEB-INF/lib directory of my project.
I tried to add el-api.jar first, then juel-2.1.0.jar to the WEB-INF/lib directory but I'm still getting these errors.
I'd like to know if someone could give me some hints about the way to deal with this. When I don't use the Jersey linking jar, everything is working as expected.
I had a similar problem with my GAE app. It was working fine with el-api and el-impl but started asking for de.odysseus.el.ExpressionFactoryImpl as development progressed. I made the switch but when I added JUEL to my pom.xml, I got the same error as John Prince (java.security.AccessControlException).
The solution for GAE users is to use JUEL 2.2.7.
At the time of this writing, 2.2.7 is not available in maven central. However, you can find it on
<repository>
<id>repo-id</id>
<name>repo-name</name>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
and link with whatever you need from
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-api</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-impl</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>de.odysseus.juel</groupId>
<artifactId>juel-spi</artifactId>
<version>2.2.7-SNAPSHOT</version>
</dependen
Source: https://github.com/beckchr/juel/issues/73
The issue is due to de.odysseus.el.ExpressionFactoryImpl class not being found. I will assume that you have added the jars as you have mentioned to the WEB-INF\lib folder.
I would suggest that you view the JAR files via theProject Explorer , simple expand them in Eclipse and see if you can find the de.odysseus.el.ExpressionFactoryImpl class in ny of the JAR files that you have added.
I "solved" the problem by adding "juel" and "juel-impl" as dependencies of my project (we're using Maven; if you're doing it manually, you might have to figure out exactly what those projects contain).
However, as soon as I did that, I started getting a different exception:
java.security.AccessControlException: access denied (java.io.FilePermission C:\Program Files (x86)\Java\jdk1.6.0_33\jre\lib\el.properties read)
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
at java.security.AccessController.checkPermission(AccessController.java:546)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
at com.google.appengine.tools.development.DevAppServerFactory$CustomSecurityManager.checkPermission(DevAppServerFactory.java:289)
...
I'm pretty sure that's because it's running afoul of GAE restrictions.
I noticed in the original ClassNotFound exception it was trying to use the URLClassLoader; I'm also wondering if that problem was ultimately a GAE issue as well.
At this point, it seems like Jersey linking support isn't compatible with GAE.
This issue is (or rather was) due to a missing implementation of the Unified Expression Language. The EL API defines a static method that looks up an implementation of the ExpressionFactory class. There are various ways to define which implementation is to be used:
Use the Services API (as detailed in the JAR specification). If a resource with the name of META-INF/services/javax.el.ExpressionFactory exists, then its first line, if present, is used as the UTF-8 encoded name of the implementation class.
Use the properties file "lib/el.properties" in the JRE directory. If this file exists and it is readable by the java.util.Properties.load(InputStream) method, and it contains an entry whose key is "javax.el.ExpressionFactory", then the value of that entry is used as the name of the implementation class.
Use the javax.el.ExpressionFactory system property. If a system property with this name is defined, then its value is used as the name of the implementation class.
Use a platform default implementation.
(Source: http://docs.oracle.com/javaee/7/api/javax/el/ExpressionFactory.html#newInstance())
App Engine appears to have defined JUEL as default implementation but does not provide the respective packages.
In order to solve this, you need to (1) provide EL API and implementation packages and (2) use one of the above ways to link it. See https://stackoverflow.com/a/19814199/2099217 for details.

jTwitter, oAuth, and Google App Engine. NoClassDefFoundError

I'm trying to use jTwitter to get an oauth instance to twitter with my consumer key/secret and access token/secret. This is well documented in the javadoc here. I have downloaded signpost, signpost-jetty, and the jtwitter library, but after deploying and running the servlet, I get a error java.lang.NoClassDefFoundError: winterwell/jtwitter/OAuthSignpostClient Eclipse isn't complaining about the class not being there, because it is there-- I can see it in the JAR file itself, which is in my project. So, I said forget it, I'll try out OAuthScribeClient instead, but this generated a VERY SIMILAR ERROR java.lang.NoClassDefFoundError: org/scribe/oauth/Token This one confuses me even further because I have the following code in my java file, and it compiles without error or warning:
import org.scribe.oauth.Token;
Token token = new Token("myaccesstokeninfo", "accesstokensecret");
Clearly, I'm missing something very fundamental, but I am at an absolute loss as to what it may be. Thanks.
Usually "NoClassDefFoundError" happens when you forget to copy all jar-files to your "/war/WEB-INF/lib" directory, so those libs will be unavailable from server-side.
Xo4yHaMope is probably right.
If you're working from Eclipse but running using a web container, then your runtime classpath might be different from your project classpath - which can cause this error.
In order to complete Ben Winters answer what I actually did and worked is add the jar in
the libs folder within the project
see also here about folder hierarchy.
When you do this eclipse will normally add the jar to the android dependencies before launching the application. What I realise is that adding a jar in the build path will make classes available only during the build

Resources