+act #3873 Adding Props.create method with manifested type
The generated classes for Java 8 lambdas doesn't carry the type information that we need, so we need to pass in the return type of the Creator.
This commit is contained in:
parent
f1edf78979
commit
c432b3e2f0
3 changed files with 59 additions and 9 deletions
|
|
@ -55,6 +55,25 @@ public class ActorCreationTest {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static class G implements Creator {
|
||||
public Object create() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testErasedCreator() {
|
||||
try {
|
||||
Props.create(new G());
|
||||
assert false;
|
||||
} catch(IllegalArgumentException e) {
|
||||
assertEquals("erased Creator types are unsupported, use Props.create(actorClass, creator) instead", e.getMessage());
|
||||
}
|
||||
Props.create(UntypedActor.class, new G());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightCreator() {
|
||||
final Props p = Props.create(new C());
|
||||
|
|
|
|||
|
|
@ -57,12 +57,27 @@ public class JavaAPI {
|
|||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Props mkErasedProps() {
|
||||
return Props.create(JavaAPITestActor.class, new Creator() {
|
||||
public Object create() {
|
||||
return new JavaAPITestActor();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mustBeAbleToCreateActorRefFromFactory() {
|
||||
ActorRef ref = system.actorOf(mkProps());
|
||||
assertNotNull(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mustBeAbleToCreateActorRefFromErasedFactory() {
|
||||
ActorRef ref = system.actorOf(mkErasedProps());
|
||||
assertNotNull(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mustBeAbleToCreateActorWIthConstructorParams() {
|
||||
ActorRef ref = system.actorOf(Props.create(ActorWithConstructorParams.class, "a", "b", new Integer(17), 18));
|
||||
|
|
|
|||
|
|
@ -100,12 +100,19 @@ object Props {
|
|||
|
||||
/**
|
||||
* Create new Props from the given [[akka.japi.Creator]].
|
||||
*
|
||||
* You can not use a Java 8 lambda with this method since the generated classes
|
||||
* don't carry enough type information.
|
||||
*
|
||||
* Use the Props.create(actorClass, creator) instead.
|
||||
*/
|
||||
def create[T <: Actor](creator: Creator[T]): Props = {
|
||||
if ((creator.getClass.getEnclosingClass ne null) && (creator.getClass.getModifiers & Modifier.STATIC) == 0)
|
||||
val cc = creator.getClass
|
||||
if ((cc.getEnclosingClass ne null) && (cc.getModifiers & Modifier.STATIC) == 0)
|
||||
throw new IllegalArgumentException("cannot use non-static local Creator to create actors; make it static (e.g. local to a static method) or top-level")
|
||||
val ac = classOf[Actor]
|
||||
val actorClass = Reflect.findMarker(creator.getClass, classOf[Creator[_]]) match {
|
||||
val coc = classOf[Creator[_]]
|
||||
val actorClass = Reflect.findMarker(cc, coc) match {
|
||||
case t: ParameterizedType ⇒
|
||||
t.getActualTypeArguments.head match {
|
||||
case c: Class[_] ⇒ c // since T <: Actor
|
||||
|
|
@ -113,9 +120,18 @@ object Props {
|
|||
v.getBounds collectFirst { case c: Class[_] if ac.isAssignableFrom(c) && c != ac ⇒ c } getOrElse ac
|
||||
case x ⇒ throw new IllegalArgumentException(s"unsupported type found in Creator argument [$x]")
|
||||
}
|
||||
case c: Class[_] if (c == coc) ⇒
|
||||
throw new IllegalArgumentException(s"erased Creator types are unsupported, use Props.create(actorClass, creator) instead")
|
||||
}
|
||||
apply(defaultDeploy, classOf[CreatorConsumer], actorClass :: creator :: Nil)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new Props from the given [[akka.japi.Creator]] with the type set to the given actorClass.
|
||||
*/
|
||||
def create[T <: Actor](actorClass: Class[T], creator: Creator[T]): Props = {
|
||||
apply(defaultDeploy, classOf[CreatorConsumer], actorClass :: creator :: Nil)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue