Sample Scala Project
This page relates to Scala
Overview
This topic describes a sample project that shows how the GigaSpaces Scala extension can be used in a real project, and how Scala and Java code can be integrated.
Using the Sample Scala Project
Requirements
The sample Scala project uses the maven
build tool. Ensure that the following requirements are met:
- The minimum required Java version is JDK 1.6 .
- To run the project, Scala libraries must be accessible to the data grid.
Scala is not needed to build the project, because the required libraries are downloaded by maven
.
Running the Example
-
Download the xap-scala package and unzip it.
-
From the project's main directory
$GS_SCALA
, run the following CLI command to install Maven on the host machine:mvn clean install
-
From the project's main directory
$GS_SCALA/example/gs-openspaces-scala-example
, run the following command to deploy the JAR files that you will need to deploy the project to the data grid:mvn clean package
-
To start the data grid, run the following command:
$GS_HOME/bin/gs-agent.sh/bat
-
Run this command
$GS_HOME\bin\gs maven install
: -
Deploy the project on the grid (from
$GS_SCALA/example/gs-openspaces-scala-example
):mvn os:deploy -Dgroups=$GS_LOOKUP_GROUPS
.
Scala Sample Project Features
Constructor-Based Properties
The Common
module defines the Space Where GigaSpaces data is stored. It is the logical cache that holds data objects in memory and might also hold them in layered in tiering. Data is hosted from multiple SoRs, consolidated as a unified data model. classes that are used by other modules. The classes are written in Scala, and are also used in other Scala and Java modules. All of these classes are translated into bytecode
and can therefore be used interchangeably.
Being in immutable state is sometimes preferable. This requirement is covered in the GigaSpaces Scala extension by classes that use constructor-based properties; in the common
module this is the Verification
class, which is written only once to the Space
and is never changed (instances can be removed).
case class Verification @SpaceClassConstructor() (
@BeanProperty
@SpaceId
id: String,
@BeanProperty
dataId: String) extends scala.Serializable {
override def toString: String = s"id[$id] dataId[$dataId]"
}
The other class (Data
) has been rewritten in Scala. However, its behavior has not been modified apart from adding a new field needed by the verifier
module:
case class Data (
@BeanProperty @SpaceId(autoGenerate = true) var id: String = null,
@BeanProperty @SpaceRouting @SpaceProperty(nullValue = "-1") var `type`: Long = -1,
@BeanProperty var rawData: String = null,
@BeanProperty var data: String = null,
@BooleanBeanProperty var processed: Boolean = false,
@BooleanBeanProperty var verified: Boolean = false) {
def this(`type`: Long, rawData: String) = this(null, `type`, rawData, null, false, false)
def this() = this(-1, null)
override def toString: String = s"id[${id}] type[${`type`}] rawData[${rawData}] data[${data}] processed[${processed}] verified[${verified}]"
}
Predicate-Based Queries
The verifier
module extends the pipeline presented in the baseline project (the one created by the OpenSpaces Maven plugin
). The Verifier
picks up processed Data
instances and tries to verify them. The objects that pass the verification process are then modified (verified
is set to true
) and saved along with a new, immutable Verification
object. The objects that fail the verification process are removed from the Space. The verifier
uses the predicate-based queries feature to access the Space in a more readable and natural way (especially for functional languages such as Scala):
@GigaSpaceContext private var gigaSpace: GigaSpace = _ // injected
// ...
// data instances to process further are obtained in the following way
val unverifiedData = gigaSpace.predicate.readMultiple { data: Data => data.processed == true && data.verified == false }
The pu This is the unit of packaging and deployment in the GigaSpaces Data Grid, and is essentially the main GigaSpaces service. The Processing Unit (PU) itself is typically deployed onto the Service Grid. When a Processing Unit is deployed, a Processing Unit instance is the actual runtime entity..xml contains a standard description of the gigaSpace:
...
<os-core:giga-space-context/>
<os-core:space-proxy id="space" space-name="mySpace"/>
<os-core:giga-space id="gigaSpace" space="space"/>
...
The gigaSpace
in the code above is an instance of ScalaEnhancedGigaSpaceWrapper, which is a wrapper around the gigaSpace
in the GigaSpaces Scala shell.
Building Scala and Mixed Java/Scala Modules
The build configuration in Scala or Java/Scala modules is almost as simple in case of pure Java modules.
Scala Module
The common
module is a pure Scala module. The build configuration from the pom.xml
for the common
module has the following form:
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaCompatVersion>${scalaBinaryVersion}</scalaCompatVersion>
</configuration>
</plugin>
</plugins>
<finalName>gs-openspaces-scala-example-common</finalName>
</build>
In the above example, scalaBinaryVersion
is a property defined in a parent pom file (in this case it is 2.11
).
Java-Scala Module
The verifier
module is a mixed Java-Scala module where Scala classes call Java classes. This configuration can be used when a separate task is implemented in Java, and it only needs to be called from other parts of the application. In this sample project, the Java module is simulated by the VerifierEngine
class and is executed by the Scala verifier
for ease of use.
In this configuration, the Scala compiler has to access the Java-compiled classes. The build-helper-maven-plugin
adds Java classes to the source, then they are compiled, and finally the Scala compiler uses them during Scala code compilation. The build configuration of the verifier
module is as follows:
<build>
<sourceDirectory>src/main/scala</sourceDirectory>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-java-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
<configuration>
<scalaCompatVersion>${scalaBinaryVersion}</scalaCompatVersion>
</configuration>
</plugin>
</plugins>
</build>