How can I code my bundle in Scala and then deploy it into OSGI container?
Do I compile it into "java" first or can i deploy scala straight into OSGI and use some kind of bundles to recognize it?
Any pointers would be great.
Currently I am using Apache Felix as my osgi-container, but just a simple explanation of generic concepts would suffice to get me started.
Thanks to everyone for the answers, you led me to the solution! I will describe it here in a little simpler terms for a wider audience.
Goal: Code in scala, deploy to OSGi.
Tools used:
Equinox OSGi implementation
Eclipse Helios 3.6,
Scala 2.9
Procedure
Install Scala IDE for Eclipse. Find version that will work with Scala 2.9 and Eclipse 3.6
Create new Scala Project in Eclipse.
Convert the project to OSGi bundle by right clicking on it and selecting: Configure -> Convert to Plug-in Projects...
Now, the next part was where I got stuck. You see, now we need to deploy this bundle (our project) to OSGi environment. However we are missing the Scala classes (or bundle that contains those classes) that have to be in OSGi container to provide all the Scala packages API we use in our bundle. Unfortunately finding the "Scala bundle" is not that easy. After looking around it turns out, that for some reason, Scala bundle is actually located in the Sonatype Maven Repository.
Download the scala-library-2.9.1.jar from the appropriate location in the Sonatype Maven Repository, and deploy it (by means most comfortable for you) to your OSGi container.
Adjust your manifest file to require the Scala bundle (I am pretty sure that this is one place where bundle dependency (i.e. Require-Bundle) is actually pretty safe - after all, you will never run your Scala code without Scala!):
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Scala Hello
Bundle-SymbolicName: com.test.scala.hello
Bundle-Version: 1.0.0.qualifier
Bundle-Vendor: drozzy
Import-Package: org.osgi.framework;version="1.5.0"
Bundle-Activator: com.test.scala.hello.Activator
Require-Bundle: scala-library;bundle-version="2.9.1"
Now, you can write your bundle activator in Scala (wooho!):
//Activator.scala
package com.test.scala.hello
import java.lang.System
import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext
class Activator extends BundleActivator {
def start(context: BundleContext) {
System.out.println("Hello world from scala!");
}
def stop(context: BundleContext){}
}
Deploy your project as a bundle to OSGi container and look out for the "Hello world from scala!" message.
ScalaModules
A quick intro video by the author here Scala days 2010
OSGi does not care what language you write your code in: JVM bytecode is just JVM bytecode. So:
compile with Scala
wrap the resulting classes in a bundle using bnd (just as you would for code compiled from Java sources).
deploy the bundle to OSGi, just as you would for a "normal" bundle (because it is a normal bundle).
You'll notice that your bundle has dependencies on the Scala library. Again there is nothing strange about this, it's just like having dependencies in you Java code. In order for those dependencies to resolve, you need to install the Scala library bundle from scala-lang-osgi
There is nothing special to it: write your code in Scala and wrap it up as an OSGi bundle by providing the necessary bundle meta data and service descriptors as you would do with Java.
Apache Maven can help you in the process. Have a look at the Guggla Project (a Scala script engine) for a working example. The maven-bundle-plugin in the pom.xml takes care of generating and including the bundle meta data in the final jar file. It refers to the service descriptor xml file which you need to provide.
Related
I'm packaging my application with the sbt native-packager using Java application archetype and Debian format.
According to their documentation, the Java application archetype produces a start script, which declares runtime classpath like the following:
declare -r app_classpath="$lib_dir/..."
I'm wondering where this classpath comes from and how the native-packager manages to get this classpath.
Native-packager uses the dependencyClasspath in Runtime task and the dependent sub modules to build the classpath.
You can see the concrete implementation here:
https://github.com/sbt/sbt-native-packager/blob/master/src/main/scala/com/typesafe/sbt/packager/archetypes/JavaAppPackaging.scala#L52
Cheers,
Muki
Using GGTS 3.6.0M1 with Grails 2.4, I have a java class file that needs an external jar to compile. That jar is defined in BuildConfig.groovy in the "compile" stage, but Eclipse still complains that the references class is not found (because it's not in the Java Build Path).
Since dependency management is performed by Grails, what's the best way to handle dependencies from Java classes that are within Grails projects?
EDIT: Refresh-dependencies doesn't solve the problem of my JAVA classes (under src/java) not seeing the jars in their classpath within Eclipse (showing project errors). If I compile externally - it works (grails compile).
I've got a Scala project that is built with Gradle. The Scala code is source compatible with scala 2.9 and 2.10 and I'd like to cross build it to both major Scala versions. Does Gradle support this?
For example, my gradle project will have a single module:
build.gradle
src/main/scala/foo.scala
and I'd like the resulting published jars to be:
org-foo_2.9-0.1.jar (with dependency on scala-library 2.9)
org-foo_2.10-0.1.jar (with dependency on scala-library 2.10)
Gradle's Scala plugin doesn't currently support cross-building. It's possible to implement it yourself, though. In my Polyglot Gradle talk, I presented a proof-of-concept.
I am searching for a good example of this. The Gradle manual doesn't mention how to specify Scala version but looking at the source code for the Scala plugin it seems to infer it from the Scala library jar that you specify.
The best example I could find is the Apache Kafka build system. It specifies the Scala version and then uses some additional logic to resolve the correct version of the Scala libraries. It also uses some logic to attach the correct label to the jars its builds to correspond to the correct Scala version.
This feels like a lot of work and something that the build system should do for you like in SBT.
I can't launch a scala jar; when I launch it I get the error "Exception in thread "main" java.lang.NoClassDefFoundError: scala/collection/immutable/List" which seems to mean the scala library is not loaded...
this is a screenshot showing a lot of informations on the artifact window.
here is the manifest:
Manifest-Version: 1.0
Class-Path: libs/scala-library-2.10.0.jar libs/commons-logging-1.1.1.j
ar libs/jcip-annotations-1.0.jar libs/jwnl-1.4_rc3.jar libs/laf-plugi
n-7.2.1.jar libs/laf-widget-7.2.1.jar libs/miglayout-core-4.2.jar lib
s/miglayout-swing-4.2.jar libs/scala-actors.jar libs/scala-library.ja
r libs/scala-swing.jar libs/slf4j-api-1.6.4.jar libs/slick_2.10-1.0.0
.jar libs/sqlite-jdbc-3.7.2.jar libs/substance-7.2.1.jar libs/trident
-7.2.1-swing.jar
Main-Class: Fenetre
and when I enter "java xf myJar.jar", there are extracted files in the directory:
- .class files
- in the libs folder, there are the libraries INCLUDING scala-library.jar & scala-library-2.10.0.jar(I specified only one of these two files in the manifest to avoid conflicts)
can you help me?
I'm new to Scala and don't know what the problem is however I've been compiling "fat jars" which include all the required libs.
I've been using https://github.com/sbt/sbt-assembly to do this successfully.
Despite what your manifest is telling you, when you run the application you either do not have the scala-library included in your class path or there's some confusion when you attempt to import List. Scala should automatically import the immutable collection classes in your project with the root Predef implementation.
Predef provides type aliases for types which are commonly used, such as the immutable collection types scala.collection.immutable.Map, scala.collection.immutable.Set, and the scala.collection.immutable.List constructors (scala.collection.immutable.:: and scala.collection.immutable.Nil). The types Pair (a scala.Tuple2) and Triple (a scala.Tuple3), with simple constructors, are also provided.
Predef in core Scaladocs
Try printing the classpath from within your app to confirm.
Although not pertinent to your question, I would recommend using SBT for dependency management now that IntelliJ IDEA 13 has full SBT integration support. Your collaborators not using IntelliJ will also be happier because SBT gives them more options for build technologies, editors, and other tooling when working on the project.
I have created an atmosphere framework application. When I use Xsbt container:start it does not scan the assembly and find the annotations on my classes.
However, when I package the project as a war and deploy to tomcat, it works perfectly.
It looks like there is a classpath issue but I am not sure how to start diagnosing this. I'm not finding much by googling or tinkering
If I manually copy the classes into webapp/WEB-INF/classes and the libs into webapp/lib/ then the application works, but the debugging for atmosphere does not.
I know that sbt is adding my dependencies in /home/me/.ivy2
I fixed my problem by telling sbt to output my class files to the web-inf directory where atmosphere requires them to be put:
classDirectory in Compile := file("src/main/webapp/WEB-INF/classes")