How to deploy a Scala/akka application on Tomcat? - scala

I try to deploy a simple application in Scala using akka on Tomcat 7.
In the first version, the actor system and the main actor were started directly from a Scala object.
In the second version, I created an initializer (extending ServletContextListener) in order to start the actor system and the actor at the deployment of the war.
In both case, I get a java.lang.LinkageError like the following :
java.lang.LinkageError: loader constraint violation: when resolving method "akka.actor.Props$.apply(Lscala/reflect/ClassManifest;)Lakka/actor/Props;" the class loader (instance of org/apache/catalina/loader/WebappClassLoader) of the current class, com/my-app/Transfert$, and the class loader (instance of org/apache/catalina/loader/StandardClassLoader) for resolved class, akka/actor/Props$, have different Class objects for the type scala/reflect/ClassManifest used in the signature
com.my-app.Transfert$.<init>(Transfert.scala:14)
com.my-app.Transfert$.<clinit>(Transfert.scala)
com.my-app.Transfert.getState(Transfert.scala)
org.apache.jsp.transfert_jsp._jspService(transfert_jsp.java:85)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:433)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:389)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
I searched on Google and everywhere, but I didn't find a simple example of how to deploy a Scala/akka application on Tomcat 7 ?
I know there was an akka.http package in akka 1.3, but I want to use akka 2.0 (at least). It seems akka.http has disappeared in favor of the use of play-mini. But I would prefer not to use play-mini or play.
Is there any advice ? Any reading suggestion ? Or ??

We have Akka actors 2.1 running inside Jetty 8 - it should not be too different.
You seem to be facing ClassLoader issues (I assume you are using java 6 and do not have binary compatibilities issues).
May I suggest you try to remove scala-library.2.10.0.jar and akka-actor_2.10-2.1.0.jar from your war and drop them in the tomcat 7 lib folder ?

Related

New dependency causing java.lang.NoSuchMethodError exception

I'm working on a project that is making use of a Scala ETCD client (https://github.com/nikore/scala-etcd), this has been all fine and good until I added a Scala Fleet client (https://github.com/MonsantoCo/fleet-client) into the mix.
When I compile it is fine but once I run the project it throws the following exception on the lines where the ETCDClient is constructed
Exception in thread "main" java.lang.NoSuchMethodError: spray.json.StandardFormats$class.optionFormat(Lspray/json/StandardFormats;Lspray/json/JsonFormat;)Lspray/json/StandardFormats$OptionFormat;
at net.nikore.etcd.EtcdJsonProtocol$.optionFormat(EtcdJsonProtocol.scala:5)
at net.nikore.etcd.EtcdJsonProtocol$.<init>(EtcdJsonProtocol.scala:18)
at net.nikore.etcd.EtcdJsonProtocol$.<clinit>(EtcdJsonProtocol.scala)
at net.nikore.etcd.EtcdClient.<init>(EtcdClient.scala:76)
at net.nikore.etcd.EtcdClient$.apply(EtcdClient.scala:20)
at au.com.someproject.helpers.SomeProjectService$class.main(SomeProjectService.scala:116)
at au.com.someproject.some_agent.ServiceMain$.main(ServiceMain.scala:17)
at au.com.someproject.some_agent.ServiceMain.main(ServiceMain.scala)
The only thing that I call tell that might be causing this is that the ETCD Client requires spray-json 1.3.1 but the Fleet Client requires spray-json 1.3.2. Having a look at the compiled package, spray-json 1.3.2 is packaged.
What is the cause of this (if I am wrong about the dependencies) and how can I go about resolving this?
EDIT:
Bellow is the code at SomeProjectService.scala:116:
etcdClient = EtcdClient(s"http://${serviceConfiguration.getString("someproject.etcd.host")}:${serviceConfiguration.getString("someproject.etcd.port")}")
And bellow is the code at ServiceMain.scala:17:
object ServiceMain extends SomeProjectService {
ServiceMain is the entry point for the service but the main function is declared in the SomeProjectService trait where the etcdClient is declared

Testing Samza with RocksDB application with SBT

I would like to run a Samza (using RocksDB KV store) application from SBT. When I do ./sbt "run " I receive the following error
java.lang.ExceptionInInitializerError
(snip)
Caused by: java.lang.RuntimeException: librocksdbjni-linux64.so was not found inside JAR.
(snip)
I assume that since I run with ./run, sbt runs the classes directly, without assembling a JAR.
The dependencies are set correctly, and I've got the librocksdbjni-linux64.so inside RocksDB JAR.
Do I have to create an assembly before running?
How can I test in this case without creating an assembly?
Well, librocksdbjni-linux64.so sounds like a native library, and those usually require a little extra fiddling with things, even if they are inside the path, in order to be recognized and added. Check this question.

JBoss7 + seam2.3 = java.lang.LinkageError: loader constraint violation: when resolving overridden method

We are trying to migrate seam2.2 + jboss4.2.3 to jboss7.1.1 + seam2.3 and we are currently facing:
Caused by: java.lang.LinkageError: loader constraint violation:
when resolving overridden method
"org.jboss.seam.faces.DateConverter.getAsString
(Ljavax/faces/context/FacesContext;
Ljavax/faces/component/UIComponent;Ljava/lang/Object;)Ljava/lang/String;"
the class loader (instance of org/jboss/modules/ModuleClassLoader)
of the current class, org/jboss/seam/faces/DateConverter,
and its superclass loader (instance of org/jboss/modules/ModuleClassLoader),
have different Class objects for the type ext/FacesContext;
Ljavax/faces/component/UIComponent;
Ljava/lang/Object;)
Ljava/lang/String;
used in the signature
Base on the articles I've found on google it seems like we are loading 2x the jboss-seam jar. 1 from the app and 1 from JBoss, but I'm not 100% sure though.
Any idea what's causing the problem?
Thanks,
czetsuya
Some jars are needed to build your application, but shouldn't be deployed with it.
Check the deployed-jars.list in your Seam app and make sure you're not deploying jars already loaded by jboss.
It won't be a Seam jars, those are not included with the jboss loader unless you add them. It will probably be a JSF jar.

JBoss 6 classloader issue

I'm trying to deploy a WAR application on JBoss 6. I'm getting a LinkageError:
java.lang.LinkageError: loader constraint violation:
when resolving interface method "javax.xml.stream.XMLStreamReader.getName()Ljavax/xml/namespace/QName;" the class loader (instance of org/jboss/classloader/spi/base/BaseClassLoader) of the current class, org/codehaus/xfire/soap/handler/ReadHeadersHandler,
and the class loader (instance of <bootloader>) for resolved class, javax/xml/stream/XMLStreamReader, have different Class objects for the type javax/xml/namespace/QName used in the signature
So I'm trying to setup a classloader repository WEB-INF/jboss-web.xml file:
<class-loading>
<loader-repository java2ClassLoadingCompliance="false">
com.example:archive=unique-archive-name
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</class-loading>
but I'm still getting the same error, any ideas?
This means two copies of javax/xml/namespace/QName are being loaded by two different classloaders. This thread and this one have a couple of useful responses that should help you get started on figuring out how dig deeper and hopefully get past this problem.

websphere 7 and (application based) open-jpa 2

I want to not use the built in Websphere 7 jpa plugin, instead use an application WEB-INF/lib/open-jpa 2 and a proprietary persistence provider. I cannot install the OSGI and JPA 2 feature pack for Websphere.
Originally, I was getting a sax parse error simply trying to load the persistence.xml (version="2" not supported). The error was thrown by a class in open-jpa 1.2.3. When I run websphere/appserver/bin/wsjpaversion.bat, the open-jpa 1.2.3 jar is displayed. By default it overrides the open-jpa 2 jar in the app. I created a shared library containing the open-jpa 2 jar with this config option checked: 'Use an isolated class loader for this shared library'. I set my application classloader to load parent last and assigned it the new shared library resource. The 'version 2' error is gone, but there is another problem. When I try to initialize an EntityManager I get an error:
Caused by: javax.persistence.PersistenceException: Failed to load provider from META-INF/services
at javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver.getPersistenceProviders(PersistenceProviderResolverHolder.java:121)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:91)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
... 2 more
Caused by: java.lang.ClassCastException: com.ibm.websphere.persistence.PersistenceProviderImpl incompatible with javax.persistence.spi.PersistenceProvider
at javax.persistence.spi.PersistenceProviderResolverHolder$DefaultPersistenceProviderResolver.getPersistenceProviders(PersistenceProviderResolverHolder.java:110)
... 11 more
One more detail: inside the persistence.xml, the provider element is set to the proprietary PersistenceProviderImpl not the default Websphere persistence provider. So where is this websphere default coming from and how do I prevent it? (another important note: when I remove persistence.xml completely, I get the same error)
Thank you
Without installing the feature pack, you're fighting a losing battle. While it is possible to plug in your own JPA implementation, it is not possible to do that with JPA API — so WAS 7 ties you to the 1.0 version of JPA (see, for example, here how this is done — no class loader policy juggling will change that, though it seems tempting at first).