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.
Related
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
}
}
I am using hazelcast in my project and I want to unit test some function but i do not want it to connect to real hazelcast and perform test on it for that i created a custom mock class which simply uses scala map because in hazelcast maps also there
here is my code
trait UserRepository {
def getUserObj(id: String):Option[User]
def addToUserRepo(user: User)
}
class UserRepo extends UserRepository{
def getUserObj(id: String):Option[User] = {
val userMap = hcastClient.getMap[String, User]("UserMap")
val userObj = userMap.get(id)
Option(userObj)
}
def addToUserRepo(user: User) = {
val directUserMap: IMap[String, User] = hcastClient.getMap[String,User]("UserMap")
directUserMap.set(user.uuid, user)
}
and here i created a simple customized mocked version class where the functionality is same just; replaced it with scala map:
class UserRepoMock extends UserRepository {
val map:Map[String,User]=Map[String,User]()
def getUserMap:Map[String,User] = {
map
}
def getUserObj(id: String):User = {
val userMap = getUserMap
val userObj = userMap.get(id)
userObj
}
def addToUserRepo(user: User) = {
val userMap = getUserMap
userMap.put(user.uuid, user)
}
class UserUtil(userRepo:UserRepo) {
def addUser(user:User):Boolean={
try{
userRepo.addToUserRepo(user)
true
}
catch {
case e:Exception=>false
}
def getUser(id:String):User={
val user=userRepo.getUserObj(id)
user
}
Mow i want to unit test methods addUser and getUserof UserUtil class
by doing like this:
class UserUtilTest extends funSpec {
val userUtil=new UserUtil(new UserRepoMock)
userUtil.addUser //perform unit test on it
userUtil.getUser //perform unit test on it
// instead of doing this val userUtil=new UserUtil(new UserRepo)
}
but the compiler not allowing me to do that,there is something which i am missing, Please help me how can i achieve the desired functionality
This is the compiler error:
type mismatch; found : testhcastrepo.UserRepoMock required: com.repositories.UserRepo
Well: your utils class says:
class UserUtil(userRepo:UserRepo)
So it needs an instance of UserRepo.
But then your are passing an instance of UserRepoMock. A UserRepoMock is a UserRepository, as UserRepo is; but a UserRepoMock is not a UserRepo!
Probably it is as simple as changing the utils to
class UserUtil(userRepo:UserRepository)
to indicate that you don't want to specify a specific class. Instead you simply say: anything that has the trait will do!
Beyond that: the real answer might be: have a look at your naming habits. You see, those two names UserRepositor and UserRepo; they are pretty "close" to each other; and it is not at all clear, what the difference between the two is. If the names would be more distinct, like UserRepositoryTrait and HCastUserRepository you probably would not have made this mistake in the first place (not sure my suggestions are "good" names according to scala conventions; but they are just meant to give you an idea).
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 make a Test Class for testing Employee Service , Everything is working fine , Except when i use a Field in other function it gets null.
// field
Employee employee;
// this will be assigned to return of below
employee= employeeService.create(emp);
// this(employee) gets null
Now what is want is to use
employeeService.remove(employee.getId);
for delete test function ,
Below is my code . Kindly provide some suggestion
I am new to groovy.
package services.employee
import spock.lang.Specification
#ContextConfiguration(loader = SpringApplicationContextLoader.class,classes = Application.class)
class EmployeeSpec extends Specification{
#Autowired
EmployeeService employeeService;
Employee response = null;
def "Check if Employee exists"(){
setup:
long empid = 43;
when:
empid > 0
then:
employeeService.getEmployee(empid);
}
def "Find all Employee"(){
setup:
when:
def res = employeeService.getAllEmployees();
then:
res.size()>0;
}
def "Insert a New Employee"(){
setup:
Employee employee = new Employee();
employee.setName("Ajit Singh");
employee.setCity("Delhi");
employee.setAge(34);
when:
response = employeeService.createEmployee(employee);
then:
response.getName().equals("Ajit Singh");
}
def "Updating an Employee"(){
}
def "delete an Employee"(){
setup:
if (response.equals(null))
println("Object is null");
when:
employeeService.removeEmployee(response.empID)
then:
def res = employeeService.find(response.empID);
res == null;
}
}
While Ivans answer above works, the proper way to do this in Spock is to use the #Shared annotation:
#Shared Employee response = null
(see https://spockframework.github.io/spock/docs/1.1-rc-1/all_in_one.html#_fields)
To cite the docs why this is the proper way to do it:
Static fields should only be used for constants. Otherwise shared fields are preferable, because their semantics with respect to sharing are more well-defined.
Yes, you can use #Shared tag, variable declared with that tag is likely global variable in java or C.
I don't know what your 'createEmployee' function is returning, but that's not a problem in groovy as you can use 'def' type instead of all types.
So, you just add #Shared def response = null
Is there any way to bind with provider which interprets target's annotation value in Google Guice?
Example:
bind(Resource.class)
.annotatedWith(MyAnnotation.class)
.toProvider(new MyProvider<MyAnnotation, Resource>{
public Resource get(MyAnnotation anno){
return resolveResourceByAnnoValue(anno.value());
}
});
I want to initialize field of an Android Activity class by annotated binding.
It should have to take multiple resources by it's unique Id.
Original Way:
public class TestActivity extends Activity{
private TextView textView;
private Button testButton;
public void onAfterCreate(...){
// set UI declaration resource.
setContentView(R.layout.activity_test);
// initialize fields, it must be done after setting ui definition.
textView = (TextView) findViewById(R.id.textView);
.... initialize other fields, hook them...
...
}
I want to bind UI and it's field in declarative way, not pragmatically likes above:
#ResourceID(R.layout.activity_test)
public class TestActivity extends InjectiveActivity{
#ResourceID(R.id.textView) // Auto generated static resource id constant
private TextView textView;
#ResourceID(R.id.testButton)
private Button testButton;
...
}
This isn't possible as such.
If #MyAnnotation is a binding annotation, it will be compared using its equals method. #MyAnnotation(5) Resource will be bound to #MyAnnotation(5) Resource, and that will not match at all compared to #MyAnnotation(6) Resource. Check out this SO answer for more. As in that answer, you could loop through your possible annotation values and bind each one individually, if you feel like it.
If #MyAnnotation isn't a binding annotation, you won't be able to access it at all from your provider. As mentioned in this SO answer, it is a rejected feature to add injection-site information to the provider or dependency itself.
Your best bet is to create an #Assisted injection (or manual factory) to accept the parameter:
class MyConsumer {
final Resource resource;
#Inject MyConsumer(Resource.Factory resourceFactory) {
int previouslyAnnotatedValue = 5;
this.resource = resourceFactory.createWithValue(previouslyAnnotatedValue);
}
}
You may also consider using Custom Injections, which will let you use an arbitrary annotation other than #Inject, which may use runtime annotation values however you'd like.
Here is an example in Scala (I like using Scala for prototyping, it's Java in a different dress after all) which I came up with after wondering about it myself in Dynamic Google Juice injection depending on value of an annotation
import java.lang.reflect.{Constructor, Parameter}
import java.util.concurrent.atomic.AtomicReference
import javax.inject.{Inject, Named, Provider}
import com.google.inject.matcher.Matchers
import com.google.inject.spi.ProvisionListener.ProvisionInvocation
import com.google.inject.{AbstractModule, Binder, Guice}
import com.google.inject.spi.{DependencyAndSource, ProviderInstanceBinding, ProvisionListener}
import com.typesafe.config.ConfigFactory
import net.codingwell.scalaguice.InjectorExtensions._
import net.codingwell.scalaguice.ScalaModule
import scala.collection.JavaConverters._
object GuiceExperiments extends App {
val injector = Guice.createInjector(new MyModule())
val some = injector.instance[Some]
println(some)
some.go()
}
trait Some {
def go(): Unit
}
class Impl #Inject()(
#Named("a.a.a") hello: String,
#Named("a.a.b") bello: String,
#Named("a.b.a") kello: String
) extends Some {
override def go() = {
println(hello)
println(bello)
println(kello)
}
}
abstract class DynamicProvider[T >: Null](binder: Binder) extends Provider[T] {
private[this] val nextValue = new AtomicReference[T]
binder.bindListener(Matchers.any(), new ProvisionListener {
private[this] def tryProvide(target: DependencyAndSource): Unit = {
val dependency = target.getDependency
val injectionPoint = dependency.getInjectionPoint
val parameterIndex = dependency.getParameterIndex
injectionPoint.getMember match {
case constructor: Constructor[_] =>
val parameter = constructor.getParameters()(parameterIndex)
nextValue.set(getFor(parameter))
}
}
override def onProvision[V](provision: ProvisionInvocation[V]): Unit = {
provision.getBinding match {
case binding: ProviderInstanceBinding[_] if binding.getUserSuppliedProvider eq DynamicProvider.this =>
provision.getDependencyChain.asScala.lastOption.foreach(tryProvide)
case _ => ()
}
}
})
final override def get(): T = nextValue.getAndSet(null)
def getFor(parameter: Parameter): T
}
class MyModule extends AbstractModule with ScalaModule {
override def configure(): Unit = {
bind[Some].to[Impl]
bind[String].annotatedWith[Named].toProvider(new DynamicProvider[String](binder) {
override def getFor(parameter: Parameter): String = {
if (parameter.isAnnotationPresent(classOf[Named])) {
parameter.getAnnotation(classOf[Named]).value()
} else {
null
}
}
})
}
}
this only inserts the value of the #Named, but looks like it pretty damn works. so much for not possible.