BlazeDS is not converting Scala classes to AMF - scala

I'm new to Scala and BlazeDS. I am trying to write a very simple application where flex would call a method called getBook and the Scala service returns a Book object. There's no database involved. All I am doing is that I'm creating a new Instance of Book and returning it.
My problem is that I don't get a valid Book object on Flex as response. I'm including the code here.
Scala Book (scalaDemo.vo.Book.scala)
package scalaDemo.vo
case class Book (id:Long,name:String,authors:String)
Scala Service (scalaDemo.GreetingService.scala)
package scalaDemo
import scalaDemo.vo.Book
class GreetingService {
def sayHello = "Hello, World!"
def getBook (name:String):Book = new Book (10,name,"author")
}
Flex Side Book (vo.Book.as)
package vo
{
[RemoteClass(alias="scalaDemo.vo.Book")]
public class Book
{
public var id:Number;
public var name:String;
public var authors:String;
}
}
GreetingService.as
package services
{
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.rpc.remoting.RemoteObject;
public class GreetingService
{
protected var ro : RemoteObject = new RemoteObject ("greetingService");
public function sayHello (responder:AsyncResponder) : void {
var token : AsyncToken = ro.sayHello();
token.addResponder(responder);
}
public function getBook (name:String,responder:AsyncResponder) : void {
var token : AsyncToken = ro.getBook(name);
token.addResponder(responder);
}
}
}
remoting-config.xml
<destination id="greetingService">
<properties>
<source>scalaDemo.GreetingService</source>
<scope>application</scope>
</properties>
</destination>
I have placed the scala classes under tomcat/webapps/blazeds/WEB-INF/classes (I am using blazeds turnkey server)
Please help me.

Ok. This is where I went wrong. I'm sorry BlazeDS. I blamed you for nothing.
This was how I defined my Book Class in Scala (the wrong way)
package scalaDemo.vo
case class Book (id:Long,name:String,authors:String)
For a Scala object to be serialized by BlazeDS we need to make sure of 2 things.
Each attribute of the class should be preceded by the Annotation #BeanProperty
Each attribute of the class should be declared as var
Here is the correct definition of scalaDemo.Book that I mentioned in my question.
package scalaDemo.vo
import scala.reflect.BeanProperty
case class Book (
#BeanProperty
var id:Long,
#BeanProperty
var name:String,
#BeanProperty
var authors:String)
Daniel C. Sorbal thank you for you interest. Now my next task would be to get Hibernate talking to Scala.

Related

Neo4j 3.0.3 Stored procedures in Scala

Is there any sample Scala code available for creating stored procedures in Neo4j-3.0.3 ?
I have been trying to create one simple Scala based stored procedure. Below is the Error message I get when I copy my scala-jar file to the neo4j-plugins directory and start the neo4j server :
=================
Caused by: org.neo4j.kernel.lifecycle.LifecycleException: Component 'org.neo4j.kernel.impl.proc.Procedures#1ac0223' was successfully initialized, but failed to start. Please see attached cause exception.
at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:444)
at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:107)
at org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory.newFacade(GraphDatabaseFacadeFactory.java:140)
... 10 more
Caused by: org.neo4j.kernel.api.exceptions.ProcedureException: Unable to find a usable public no-argument constructor in the class `neoscala`. Please add a valid, public constructor, recompile the class and try again.
=================
The scala class that I have used is :
package neoproc
import org.neo4j.graphdb.GraphDatabaseService
import org.neo4j.procedure.Procedure;
import javax.ws.rs.core.{Context, Response}
class neoscala(#Context db: GraphDatabaseService) {
#Procedure
def alice():String = {
String.valueOf(db.execute( "MATCH (n:User) return n" ));
}
}
Your Scala class declares a constructor with a GraphDatabaseService argument, and the exception tells you that it only wants a no-argument constructor.
It's documented in both
the user documentation:
Only static fields and #Context-annotated fields are allowed in Procedure classes.
the Javadoc:
The procedure method itself can contain arbitrary Java code - but in order to work with the underlying graph, it must have access to the graph API. This is done by declaring fields in the procedure class, and annotating them with the Context annotation. Fields declared this way are automatically injected with the requested resource. This is how procedures gain access to APIs to do work with.
All fields in the class containing the procedure declaration must either be static; or it must be public, non-final and annotated with Context.
Apparently it's not possible to create a class with a public field in Scala, so you'll have to create a parent Java class with the public field, and extend it with your Scala class:
// ProcedureAdapter.java
public abstract class ScalaProcedureAdapter {
#Context
public GraphDatabaseService db;
}
// neoscala.scala
class neoscala extends ScalaProcedureAdapter {
// ...
}
Here is the solution for this :
We will create Class in scala :
class FullTextIndex extends JavaHelper {
#Procedure("example.search")
#PerformsWrites
def search(#Name("label") label: String,
#Name("query") query: String): Stream[SearchHit] = {
//declare your method
}
val nodes: Stream[Node] = db.index.forNodes(index).query(query).stream
val newFunction: java.util.function.Function[Node, SearchHit] = (node: Node) => new SearchHit(node)
nodes.map {
newFunction
}
}
private def indexName(label: String): String = {
"label-" + label
}
}
Procedure in Neo4j always return result in Stream and it is a latest feature in Java8 so we will also used Java Class for return the final result and For defining the public variable.
We will create Java class for result :
public class JavaHelper {
#Context
public GraphDatabaseService db;
#Context
public Log log;
public static class SearchHit {
//your result code here
}
You can refer knoldus blog for Neo4j User Defined Procedure for creating and storing Neo4j Procedure with Scala. Here you will also find sample code with git hub repository.

How to add structural links to Jersey/Moxy/JAXB XML without altering the model

I mean "structural links" in the HATEOAS/hypermedia API sense. The more general question is how to augment the generated XML with data that depends on both the entity being marshalled, and also on the environment (in this case, at least the absolute URL).
I'm using Jersey 2.9 with Moxy 2.5 as the JAXB provider.
From this model:
package testing;
import java.util.ArrayList;
import java.util.List;
public class Planet {
private int id = 1;
private String name = "test";
private double radius = 3.0;
private String href;
private List<Moon> moons = new ArrayList<Moon>(0);
public void addMoon(Moon moon) {
moons.add(moon);
}
}
...plus Moon class
I want to get something like this XML (and the equivalent JSON):
<planet href="http://mytestserver/rest/planets/test">
<name>test</name>
<radius>3.0</radius>
<moons>
<moon href="http://mytestserver/rest/moons/moon1">
<name>moon1</name>
</moon>
<moon href="http://mytestserver/rest/moons/moon2">
<name>moon2</name>
</moon>
</moons>
</planet>
The model has no "href" field, nor can one be added. Ideally I could use UriBuilder to grab these paths straight from the resource classes.
So far I've come up with several possiblities. Can I ask you to consider which (if any) has the most legs, and then how you would work around the shortcomings of that method?
1. Augment the model with AspectJ (or Javassist).
And then use the existing declarative linking mechanisms in Jersey, all of which rely on there being a field in the model to receive the generated links. This obviously won't work if you don't have AspectJ in your build process and/or balk at exotic techniques like byte code manipulation.
2. Post-process the generated XML and JSON
For example, in a MessageBodyWriter:
ContextResolver<JAXBContext> resolver = providers.getContextResolver(JAXBContext.class, mediaType);
JAXBContext context = resolver.getContext(type);
Marshaller m = context.createMarshaller();
<--- here, marshall to e.g. a DOM then transform that
<--- then manipulate the JSON structures
I have absolutely no idea how to do any of that, hence the lack of code. There may be other ways to hook into the XML generation process, but as far as I can see none of Jersey's or JAXB's event handlers or interceptors actually allow you to manipulate the generated XML/JSON.
3. Use a Moxy XMLTransformationMapping
For example:
XML binding:
<java-type name="Planet" xml-customizer="testing.HrefCustomizer">
Customizer:
public class HrefCustomizer implements DescriptorCustomizer {
#Override
public void customize(ClassDescriptor descriptor) throws Exception {
XMLTransformationMapping xtm = new XMLTransformationMapping();
xtm.addFieldTransformer("#href", new HrefWriter());
descriptor.addMapping(xtm);
}
}
Transformer:
public class HrefWriter implements FieldTransformer {
#Override
public Object buildFieldValue(Object instance, String fieldName,
Session session) {
return "href"; // constant value just for proof-of-concept
}
#Override
public void initialize(AbstractTransformationMapping mapping) {
// TODO Auto-generated method stub
}
}
I have two problems with this approach:
It was so hard to find any documentation on it that I wonder if it is in fact unsupported usage.
I can't see how the transformer is going to get a UriBuilder to work with. At minimum it would need the root URL of the rest service.
4. Slightly different Moxy xml-transform approach
If we decide we can't provide the transformer with any meaningful context at instantiation time, the customizer is adding no value and we can simplify the above to just this:
<java-type name="Planet">
<xml-root-element/>
<java-attributes>
<xml-transformation java-attribute="name">
<xml-write-transformer transformer-class="testing.HrefWriter" xml-path="#href"/>
</xml-transformation>
<xml-element java-attribute="name"/>
With the slight oddity that we are hanging the transformer off another field ("name", in this example).
5. ?????
Or, I'm completely barking up the wrong tree. Help!!
AspectJ approach
Synopsis
Use AspectJ to add a field to the model classes (called "href" in this example)
Add the Jersey #InjectLink annotation to that field
Jersey will then populate the field with the right URL as defined by the resource class
Specify the marshaling of the href field using an external mapping file.
You could also specify the marshaling of href by adding JAXB annotations to it via the same AspectJ intertype declaration mechanism.
Example code
These are the most informative bits. See http://lagod.id.au/blog/?p=494 for the full example.
The aspect
package testing;
import org.glassfish.jersey.linking.InjectLink;
import org.glassfish.jersey.linking.Binding;
public aspect HrefInjector {
private String Planet.href;
declare #field : * Planet.href : #InjectLink(
resource=Services.class,
style=InjectLink.Style.ABSOLUTE
) ;
private String Moon.href;
declare #field : * Moon.href : #InjectLink(
resource=Services.class,
method="moon",
bindings={#Binding(
name="moonid", value="${instance.name}"
)},
style=InjectLink.Style.ABSOLUTE
) ;
}
Model classes
POJOs with no REST-specific cruft. See Jersey + Moxy + JAXB - how to marshal XML without annotations.
package testing;
import java.util.ArrayList;
import java.util.List;
public class Planet {
private int id = 1;
private String name = "test";
private double radius = 3.0;
private List<Moon> moons = new ArrayList<Moon>(0);
public void addMoon(Moon moon) {
moons.add(moon);
}
}
package testing;
public class Moon {
private String name;
// No-arg constructor is a requirement of JAXB
public Moon() {
}
public Moon(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Resource class
This is a standard JAX-RS resource class. For demo purposes, we're just returning freshly instantiated model instances.
package testing;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
#Path("/services")
#Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})
public class Services {
private Planet initPlanet() {
Planet p = new Planet();
p.addMoon(new Moon("moon1"));
p.addMoon(new Moon("moon2"));
return p;
}
#GET
public Planet planet () {
return initPlanet();
}
#GET #Path("/moons/{moonid}")
public Moon moon (#PathParam("moonid") String name) {
return new Moon(name);
}
}
Moxy mapping file
Note that you can choose for any given type whether or not you want to actually marshal the href field. In fact, by using multiple mapping files, you can include the href field in some representations and not in others.
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="testing"
xml-mapping-metadata-complete="true"
xml-accessor-type="NONE">
<java-types>
<java-type name="Planet">
<xml-root-element/>
<java-attributes>
<xml-attribute java-attribute="href"/>
<xml-element java-attribute="name"/>
<xml-element java-attribute="radius"/>
<xml-element java-attribute="moons" name="moon">
<xml-element-wrapper name="moons"/>
</xml-element>
</java-attributes>
</java-type>
<java-type name="Moon">
<xml-root-element/>
<java-attributes>
<xml-attribute java-attribute="href"/>
<xml-element java-attribute="name"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
Sample output
Ta-dah! Structural links derived automatically from the JAX-RS resource class without altering model source code. Because we're using Moxy, we also get JSON for free.
<planet href="http://localhost:8080/reststructlinks/rest/services">
<name>test</name>
<radius>3.0</radius>
<moons>
<moon href="http://localhost:8080/reststructlinks/rest/services/moons/moon1">
<name>moon1</name>
</moon>
<moon href="http://localhost:8080/reststructlinks/rest/services/moons/moon2">
<name>moon2</name>
</moon>
</moons>
</planet>

TypeScript module and class simultaneously?

I am currently trying to build a TypeScript definition file for OpenLayers.
The problem is that in OpenLayers there are certain classes that would translate to both a module and a class in TypeScript.
For example there is the Protocol class in module OpenLayers and there is a class Response in module OpenLayers.Protocol.
How could I model that in TypeScript? Can I make Protocol a class and define the Response class as a inner class that is exported? How would you go about solving that problem?
Declare Response as a static field of Protocol with a constructor type, returning an interface that defines the Response class:
declare module OpenLayers {
export interface IProtocolResponse {
foo(): void;
}
export class Protocol {
static Response: new () => IProtocolResponse;
}
}
var response = new OpenLayers.Protocol.Response();
response.foo();
Edit:
Or as Anders points out in this discussion list question, you can have multiple constructors for the inner class in this way:
declare module OpenLayers {
export interface IProtocolResponse {
foo(): void;
}
export class Protocol {
static Response: {
new (): IProtocolResponse;
new (string): IProtocolResponse;
};
}
}
var response = new OpenLayers.Protocol.Response('bar');
response.foo();
The main downside of both approaches is that you cannot derive a class from OpenLayers.Protocol.Response.
Here is my updated answer, which I hope helps - it should get you started on defining OpenType:
declare module OpenType {
export class Protocol {
constructor();
Request;
}
}
var x = new OpenType.Protocol();
var y = new x.Request();
var z = x.Request;

DataContractSerializer. Serializing class through interface

I have class that implements some interface:
[DataContract]
public class ScriptState : IScriptState
{
<...>
}
I have simple helper class
public class Serializer
{
string Serialize<T>(T obj)
{
MemoryStream ms = new MemoryStream();
DataContractSerializer ser = new DataContractSerializer(typeof(T));
ser.WriteObject(ms, obj);
<...>
}
}
the problem is that I have loose coupled application and I get ScriptState object something like this:
IScriptstate ss = ServiceLocator.Resolve<IScriptState>();
i.e. variable has type of interface, and it is being processed by serializer:
Serializer.Serialize(ss);
and because of this DataContracrSerializer is instantiated with type of interface IScriptState, but real type of object is ScriptState, which leads to error, that type ScriptState is not expected.
Standard workaround should be adding knowntype ScriptState to interface IScriptState, but I can't do this obviously:
[KnownType(typeof(Scriptstate))]
IScriptState
{}
because assembly with interface has no reference to assembly with class.
Is there another solution??
I think I've found solution. In helper class use obj.GetType() instead of typeof(T) :
DataContractSerializer ser = new DataContractSerializer(obj.GetType());

How to call Grails from Scala

Is there a way to call a method in a Grails service, from a Scala class that is running on the same JVM?
I have seen something similar done from Groovy/Griffon but cannot figure out how to accomplish that in Grails. (http://www.jroller.com/aalmiray/entry/griffon_groovy_scala_working_together)
Basically, one of my Grails controllers calls some Scala code, which should return some values asynchronously. So, I guess, the only way to return those values is by calling back a method in a Grails service.
I found a way of doing it, inspired by the link in the question above, and one of the FAQs in the Grails website.
On the Scala side:
Declare an object similar to the following:
package scalaCallback
object ScalaCallback{
var cback: {def callback(example: String)} = null
def setCallback(cb: {def callback(example: String)}){
cback = cb
}
def invokeCallback(example: String){
if(callback != null) cback.callback(example)
}
}
On the Grails side:
Create a class in src/groovy similar to the following:
package groovyCallback
import org.codehaus.groovy.grails.commons.ApplicationHolder
class GroovyCallback{
private GroovyCallback() {}
private static final INSTANCE = new GroovyCallback()
static getInstance(){ return INSTANCE }
void callback(String example){
ApplicationHolder.application.mainContext.yourService.yourMethod(example)
}
}
In your BootStrap.groovy init add the following:
scalaCallback.cback = groovyCallback.GroovyCallback.getInstance()
When you call invokeCallback("example") in Scala, it will call yourService.yourMethod("example")
Note: the jar file with your Scala class should be in the lib folder of you Grails application
Your Grails service is a Spring bean. #Autowire the service into your Scala class (it will need to be a bean/#Component) and call the method.
EDIT - added example:
For example (using Java, not Scala but the approach is exactly the same):
Java code calling service:
package grailstest;
#Component
public class ServiceInjectionTester {
#Autowired TestService testService;
public String testTheService() {
return testService.serviceMethod();
}
}
Service:
class TestService {
String serviceMethod() {
return "success"
}
}
In Config.groovy:
grails.spring.bean.packages = [ "grailstest" ]
You can also wire your Java/Scala bean into your Grails classes:
class TestController {
#Autowired
ServiceInjectionTester serviceInjectionTester
def index = {
render(text: serviceInjectionTester.testTheService())
}
}
References:
Grails Reference 8.4 - Using Services from Java
Spring: The Foundation for Grails