What is kotlin equivalent of this java class?
public class StatefulActor extends AbstractActor<StatefulActor.State> implements Some
{
public static class State
{
String lastMessage;
}
}
I tried:
class HelloActor: AbstractActor<HelloActor.State>(), Hello
{
inner class State {
var lastMessage: String? = null
}
but results in Cloud.orbit.exception.UncheckedException: Don't know how to handle state
What is kotlin equivalent of this java class?
Your Kotlin and Java code differs in two ways, the relationship of the State to StatefulActor and the ability of State to allow subclassing.
For State what you want is a Nested class not an Inner class in Kotlin terms. The former corresponds to static modifier in Java whereas the latter is like an inner class without the static modifier.
So for equivalence with the Java code you gave, you should drop the inner keyword.
Cloud.orbit.exception.UncheckedException: Don't know how to handle state
As for your Orbit problem you can try the following. This will also explain why subclassing is an issue:
// compile and run with cloud.orbit:orbit-runtime:1.2.0
import cloud.orbit.actors.runtime.AbstractActor
import cloud.orbit.actors.Actor
import cloud.orbit.actors.Stage
import cloud.orbit.concurrent.Task
class HelloActor: AbstractActor<HelloActor.ActorState>(), Hello
{
override fun sayHello(greeting: String): Task<String> {
val lastMessage = state().lastMessage
state().lastMessage = greeting
return Task.fromValue(lastMessage)
}
class ActorState {
var lastMessage: String? = null
}
}
interface Hello : Actor {
fun sayHello(greeting: String): Task<String>
}
fun main(args : Array<String>) {
val stage = Stage.Builder().clusterName("orbit-helloworld-cluster").build()
stage.start().join()
stage.bind()
val helloActor = Actor.getReference(Hello::class.java, "0");
var response = helloActor
.sayHello("Welcome to orbit 1").join()
println(response) // should print null
response = helloActor
.sayHello("Welcome to orbit 2").join()
println(response) // should print "Welcome to orbit 1"
stage.stop().join()
}
Notice that the Actor's nested class is called ActorState and not State as in your question. When I named the Actor's state class State I got a similar error:
cloud.orbit.exception.UncheckedException: Don't know how to handle state: HelloActor$State...
Caused by: cloud.orbit.exception.UncheckedException: cloud.orbit.exception.UncheckedException: Don't know how to handle state: HelloActor$State
Caused by: cloud.orbit.exception.UncheckedException: Don't know how to handle state: HelloActor$State
Caused by: cloud.orbit.exception.UncheckedException: java.lang.ClassNotFoundException: HelloActor$ActorState
But when I used the nested class name HelloActor.ActorState instead it works.
This is because by default all classes in Kotlin are closed (i.e. final in Java terms).
By default, all classes in Kotlin are final, which corresponds to Effective Java, Item 17: Design and document for inheritance or else prohibit it.
While in orbit 1.2.0 the code (if you do not use the special name ActorState) tries to subclass your State class and then instantiate it. This will not work if you go with the closed Kotlin default extensibility.
If you wish to use your own name for the Actor's state class you must declare it as open. e.g.
class HelloActor: AbstractActor<HelloActor.State>(), Hello
{
override fun sayHello(greeting: String): Task<String> {
val lastMessage = state().lastMessage
state().lastMessage = greeting
return Task.fromValue(lastMessage)
}
open class State {
var lastMessage: String? = null
}
}
Related
I'm currently designing database for a mobile application. Recently I found very useful function to access database in background:
private val IO_EXECUTOR = Executors.newSingleThreadExecutor()
fun ioThread(f : () -> Unit) {
IO_EXECUTOR.execute(f)
}
Besides that I figured out that don't need synchronization code as the database will be accessed only in one thread (i.e the thread used by SingleThreadExecutor).
The only issue is that the following methods have to be restricted to be invoked only through ioThread function (or using IO_EXECUTOR).
abstract class MyDatabase : RoomDatabase() {
companion object {
fun init(context: Context) { ... }
fun getInstance() { ... }
}
Is it possible to achieve this in Kotlin/Java?
UPDATE: for now I have this implementation but think there should be better ones
// App.kt file
private val IO_EXECUTOR = Executors.newSingleThreadExecutor()
private var IO_THREAD_ID: Long = -1L
private fun getIOThreadId(): Long {
if (IO_THREAD_ID == -1L)
IO_THREAD_ID = IO_EXECUTOR.submit(Callable<Long> { Thread.currentThread().id }).get()
return IO_THREAD_ID
}
fun notInIOThread() = Thread.currentThread().id != getIOThreadId()
fun ioThread(f : () -> Unit) {
IO_EXECUTOR.execute(f)
}
and then use notInIOThread() in init() and getInstance() functions
If you absolutely need to make sure that the code is running on the correct thread, you could make use of a custom thread and then checking Thread.currentThread() for the interface.
private interface MarkedIOThread // Marker interface
private val IO_EXECUTOR = Executors.newSingleThreadExecutor { r ->
return object : Thread(r), MarkedIOThread
}
fun notInIOThread(): Boolean = Thread.currentThread() !is MarkedIOThread
Yes, you can use android annotations`s Worker Thread annotation.
When you annotate a method or class with #WorkerThread, android will give you lint errors if you call it from the UI thread.
You can read more about the #WorkerThread here: https://developer.android.com/reference/android/support/annotation/WorkerThread
And more about android annotations here: https://developer.android.com/studio/write/annotations
I would suggest that you should check room library: https://developer.android.com/topic/libraries/architecture/room
It is very powerful, if you don't have any specific reason to create a database library, room is your best bet.
I assume you want the functions to be called only inside ioThread code block, otherwise there'd be a type error. First make them member functions of a class with user-code-inaccessible constructor so others cannot call it directly:
class MyDslClass internal constructor() {
fun init(context: Context) { ... }
fun getInstance() { ... }
}
And ioThread should be:
fun ioThread(f : MyDslClass.() -> Unit) {
val dsl = MyDslClass()
IO_EXECUTOR.execute { dsl.f() }
}
Then you can restrict calls to those functions only inside ioThread block.
fun main(args: Array<String>) {
ioThread {
getInstance() // Ok
}
// cannot call `getInstance` since I cannot construct a `MyDslClass`
}
I would like to expose a public API (a kind of Runnable) and let users implement it, and then execute that code against our servers (given the class name containing the code to run). Users provide a jar containing their implementation and should not have access to implementation details.
Below is a snippet illustrating the issue.
The public API:
package mypackage
trait MyTrait {
def run(i: Int) : Unit
}
A sample user's implementation:
package mypackage
object MyImpl extends MyTrait {
override def run(i : Int) : Unit = {
println(i)
}
}
The server-side code running the user's code:
package mypackage
import scala.reflect.runtime.{universe => ru}
object MyTest extends App {
val m = ru.runtimeMirror(getClass.getClassLoader)
val module = m.staticModule("mypackage.MyImpl")
val im = m.reflectModule(module)
val method = im.symbol.info.decl(ru.TermName("run")).asMethod
val objMirror = m.reflect(im.instance)
objMirror.reflectMethod(method)(42)
}
The above code works (printing "42"), but the deisgn seems ugly to me.
In addition it seems unsafe (class instead of object, object that does not exist or does not implement the correct interface).
What's the best way to achieve this ?
I am using Scala 2.11.8.
Thanks for your help
I am new to Scala and I need to have a scala wrapper for my Java API
I have three Java Interfaces
public interface Client<T> {
<T> Future<T> execute(App<T> app);
}
public interface App<T> extends Serializable{
T process(AppContext context) throws Exception;
}
public interface AppContext {
File getDirectory();
void deleteDirectory();
File createDirectory(String path);
}
Following is the Java code to create an App
public class RandomApp extends App<String> {
#Override
public String process(AppContext context) {
// Inorder to access the methods in AppContext I need to access
// it by the following way
appContext.createDirectory("some path");
return "random";
}
}
I want to have a Scala Wrapper for the Client Interface which in turn call the Java API. But I have some modifications for the new Scala API
object ScalaConverter {
implicit class ScalaWrapper(client: Client) {
def scalaClient = new ScalaClient(client)
}
}
class ScalaClient(client: Client) {
def execute[T](appContext: AppContext => T): Future[T] = {
// I am passing appContext as closure instead of passing in
// App because I want to take the advantage of Closures in Scala
// I basically want to create an App with this appContext and
// pass it to the execute method
// For example - but this is not working
var app = // Need to create this app with appContext
Future {
client.execute(app)
}
}
}
If I'm not mistaken, you just want to be able to create App objects from a function that takes a AppContext as parameter and returns a any object (let's say T).
As it's not really interesting to try to mirror the whole java API, just use it as it is, but add some extensions. And to do this you should use implicits.
To do this, I see two possibilities: either add an implicit class on the Client interface to add some functions to it, or add an implicit conversion from (AppContext => T) to App objects.
Let's got with the first solution, you have to embed the implicit class in an object (this can be a package object if you need automatic imports).
object ScalaConverter {
class ScalaApp[T](val block: AppContext => T) extends App[T] {
def process(context: AppContext): T = block(context)
}
implicit class ScalaClient(client: Client) extends AnyVal{
def execute[T](block: AppContext => T): Future[T] = {
client.execute(new ScalaApp(block))
}
}
}
Then, you just have to use your existing java Client object:
import ScalaConverter._
myJavaClient.execute { context =>
???
}
You should get the principle, I maybe made a mistake (did not tried to compile this)
I am trying to write integration test for my scala application(with akka-http). I am running into a problem, for which I am not able to find a solution.
My Case classes are as below:
case class Employee(id:Long, name:String, departmentId:Long, createdDate:Timestamp) extends BaseEntity
case class EmployeeContainer(employee:Employee, department:Department) extends BaseEntity
I have a method like this
trait BaseTrait[E<:BaseEntity, C <: BaseEntity]{
def getById(id:Long): Future[List[C]] = {
//query from db and return result.
}
def save(obj:E) = {
//set the createDate field to the current timestamp
//insert into database
}
}
I can extend my class with BaseTrait and just override the getById() method. Rest of the layers are provided by our internal framework.
class MyDao extends BaseTrait[Employee, EmployeeContainer] {
override def getById(id:Long) = {
for {
val emp <- getFromDb(id)
val dept <- DeptDao.getFromDb(emp.departmentId)
val container = EmployeeContainer(emp,dept)
} yield(container)
}
}
So in the rest layer, I will be getting the response as the EmployeeContainer. The problem now I am facing is that, the modified date is automaticaally updated with the current timestamp. So, when I get back the result, the timestamp in the object I passed to save() method will be overwritten with the current time. When I write the test case, I need to have an object to compare to. But the timestamp of that object and the one I get abck will never be the same.
Is there anyway, in which I can replace all the occurrance of createDate with a known value of timestamp so that I can compare it in my testcase? The main problem is that I can not predict the structure of the container (it can have multiple case classes(nested or flat) with or without createDate fields).
I was able to replace the field using reflection if it comes in the main case class, but unable to do for nested structures.
You probably need to use some for of Inversion of Control. Your main problem is that you are calling the db directly: val emp <- getFromDb(id) and thus have no control on a test of the values that are received. Calling the DB on a unit test is also arguably a bad idea, since it expands the unit to the entire database layer. You want to test a small, self-contained unit.
A simple solution is to encapsulate your DB calls as an interface and pass an instance of that interface. For instance:
class MyDao extends BaseTrait[Employee, EmployeeContainer](val dbCall: Long => Employee) {
override def getById(id:Long) = {
for {
val emp <- dbCall(id)
val dept <- DeptDao.getFromDb(emp.departmentId)
val container = EmployeeContainer(emp,dept)
} yield(container)
}
}
Then you can simply use new MyDao(getFromDb) for normal code and val testDao = new MyDao(id => Employee(id, myFixedName, myFixedDeptID, myFixedTestDate)) from test code.
I don't know why but the class below doesn't work if instance variable text is private, but if I leave out private, it works.
Debugging the test in section "setField" I could see that the instance variable name should be "text" but it becomes "com$test$SimpleTest$$text"
package com.test
import org.testng.annotations.Test
import org.springframework.test.util.ReflectionTestUtils
class SimpleTest {
private var text = ""
#Test
def testValueOfX(): Unit = {
val simpleTest = new SimpleTest
ReflectionTestUtils.setField(simpleTest,"text", "abc")
println(
Option[String](null)
.map(v => v + " 123")
.getOrElse {
simpleTest.text + " 321"
})
}
}
I believe that the problem someway be the "getOrElse" because if I leave out too, it works.
Scala compiler has a right to compile your private field into an any working java code, as it doesn't affect interoperability (if you don't do any tricks). Spring's setField actually do such trick, as it makes your private field accessible (setAccessible(true) inside). Public fields are always compiling as is to give you appropriate interface from Java.
Use http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html to work with Scala reflection. Also this article may be helpful.
Here is explanation why scalac uses another name for private field.
P.S. The reason why removing .getOrElse(text) make it work is because you don't use text anywhere but inside this piece of code.
This class is only to show the problem, actually it is very different of real class. So I changed the strategy to receive an instance by #Autowired a method instead #Autowired a field.
package com.test
import org.testng.annotations.Test
import org.springframework.test.util.ReflectionTestUtils
class SimpleTest {
// item 1
private var text = ""
#Test
def testValueOfX(): Unit = {
val simpleTest = new SimpleTest
ReflectionTestUtils.invokeSetterMethod(simpleTest, "text", "abc")
println(
Option[String](null)
.map(v => v + " 123")
.getOrElse {
simpleTest.text + " 321"
})
}
// item 2
def setText(text: String): Unit = {
this.text = text
}
}
I'm not using #Autowired in this sample but in the real class I am. So if you need to get an instance follow instructions below.
Item 1 -> if I put on #Autowired it doesn't work because like said dk14 Scala compiler has a right to compile your private field into an any working java code. So, the compiler change the field's name when it compiles the class
Item 2 -> I put on #Autowired in the setter method, it works.