diff --git a/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java b/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java index 7070e8bf67..72eda74c70 100644 --- a/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java +++ b/akka-actor-tests/src/test/java/akka/actor/JavaAPI.java @@ -1,7 +1,12 @@ package akka.actor; import akka.actor.ActorSystem; +import akka.event.Logging; +import akka.event.Logging.LoggerInitialized; import akka.japi.Creator; +import akka.routing.CurrentRoutees; +import akka.routing.FromConfig; +import akka.routing.NoRouter; import akka.testkit.AkkaSpec; import org.junit.AfterClass; @@ -23,6 +28,23 @@ public class JavaAPI { system.shutdown(); system = null; } + + // compilation tests + @SuppressWarnings("unused") + public void mustCompile() { + final Kill kill = Kill.instance(); + final PoisonPill pill = PoisonPill.instance(); + final ReceiveTimeout t = ReceiveTimeout.instance(); + + final LocalScope ls = LocalScope.instance(); + final NoScopeGiven noscope = NoScopeGiven.instance(); + + final LoggerInitialized x = Logging.loggerInitialized(); + + final CurrentRoutees r = CurrentRoutees.instance(); + final NoRouter nr = NoRouter.instance(); + final FromConfig fc = FromConfig.instance(); + } @Test public void mustBeAbleToCreateActorRefFromClass() { diff --git a/akka-actor/src/main/scala/akka/actor/Actor.scala b/akka-actor/src/main/scala/akka/actor/Actor.scala index e7337924fd..373bedfc1e 100644 --- a/akka-actor/src/main/scala/akka/actor/Actor.scala +++ b/akka-actor/src/main/scala/akka/actor/Actor.scala @@ -28,13 +28,22 @@ trait NoSerializationVerificationNeeded case class Failed(cause: Throwable) extends AutoReceivedMessage with PossiblyHarmful -case object PoisonPill extends AutoReceivedMessage with PossiblyHarmful +abstract class PoisonPill extends AutoReceivedMessage with PossiblyHarmful +case object PoisonPill extends PoisonPill { + def instance = this +} -case object Kill extends AutoReceivedMessage with PossiblyHarmful +abstract class Kill extends AutoReceivedMessage with PossiblyHarmful +case object Kill extends Kill { + def instance = this +} case class Terminated(@BeanProperty actor: ActorRef) extends PossiblyHarmful -case object ReceiveTimeout extends PossiblyHarmful +abstract class ReceiveTimeout extends PossiblyHarmful +case object ReceiveTimeout extends ReceiveTimeout { + def instance = this +} /** * ActorRefFactory.actorSelection returns a special ref which sends these diff --git a/akka-actor/src/main/scala/akka/actor/Deployer.scala b/akka-actor/src/main/scala/akka/actor/Deployer.scala index cc6db0bbda..17bdbec4b0 100644 --- a/akka-actor/src/main/scala/akka/actor/Deployer.scala +++ b/akka-actor/src/main/scala/akka/actor/Deployer.scala @@ -63,12 +63,16 @@ trait Scope { } //TODO add @SerialVersionUID(1L) when SI-4804 is fixed -case object LocalScope extends Scope { +abstract class LocalScope extends Scope +case object LocalScope extends LocalScope { /** * Java API */ + @deprecated("use instance() method instead", "2.0.1") def scope: Scope = this + def instance = this + def withFallback(other: Scope): Scope = this } @@ -76,8 +80,11 @@ case object LocalScope extends Scope { * This is the default value and as such allows overrides. */ //TODO add @SerialVersionUID(1L) when SI-4804 is fixed -case object NoScopeGiven extends Scope { +abstract class NoScopeGiven extends Scope +case object NoScopeGiven extends NoScopeGiven { def withFallback(other: Scope): Scope = other + + def instance = this } /** diff --git a/akka-actor/src/main/scala/akka/event/Logging.scala b/akka-actor/src/main/scala/akka/event/Logging.scala index 93019318dd..4bc3bf6b41 100644 --- a/akka-actor/src/main/scala/akka/event/Logging.scala +++ b/akka-actor/src/main/scala/akka/event/Logging.scala @@ -588,12 +588,16 @@ object Logging { * InitializeLogger request. If initialization takes longer, send the reply * as soon as subscriptions are set-up. */ - case object LoggerInitialized + abstract class LoggerInitialized + case object LoggerInitialized extends LoggerInitialized { + def instance = this + } /** * Java API to create a LoggerInitialized message. */ - def loggerInitialized() = LoggerInitialized + // weird return type due to binary compatibility + def loggerInitialized(): LoggerInitialized.type = LoggerInitialized class LoggerInitializationException(msg: String) extends AkkaException(msg) diff --git a/akka-actor/src/main/scala/akka/routing/Routing.scala b/akka-actor/src/main/scala/akka/routing/Routing.scala index 97ac930b78..3650779609 100644 --- a/akka-actor/src/main/scala/akka/routing/Routing.scala +++ b/akka-actor/src/main/scala/akka/routing/Routing.scala @@ -17,7 +17,8 @@ import java.util.concurrent.locks.ReentrantLock import akka.jsr166y.ThreadLocalRandom import akka.util.Unsafe import akka.dispatch.Dispatchers -import annotation.tailrec +import scala.annotation.tailrec +import scala.runtime.ScalaRunTime /** * A RoutedActorRef is an ActorRef that has a set of connected ActorRef and it uses a Router to @@ -343,7 +344,10 @@ case class Broadcast(message: Any) * A RouterRoutees message is sent asynchronously to the "requester" containing information * about what routees the router is routing over. */ -case object CurrentRoutees +abstract class CurrentRoutees +case object CurrentRoutees extends CurrentRoutees { + def instance = this +} /** * Message used to carry information about what routees the router is currently using. @@ -365,21 +369,23 @@ case class Destination(sender: ActorRef, recipient: ActorRef) * router is taken in the LocalActorRefProvider based on Props. */ //TODO add @SerialVersionUID(1L) when SI-4804 is fixed -case object NoRouter extends RouterConfig { +abstract class NoRouter extends RouterConfig +case object NoRouter extends NoRouter { def createRoute(props: Props, routeeProvider: RouteeProvider): Route = null def routerDispatcher: String = "" def supervisorStrategy = null override def withFallback(other: RouterConfig): RouterConfig = other + + def instance = this } /** * Router configuration which has no default, i.e. external configuration is required. */ -case object FromConfig extends RouterConfig { - def createRoute(props: Props, routeeProvider: RouteeProvider): Route = - throw new ConfigurationException("router " + routeeProvider.context.self + " needs external configuration from file (e.g. application.conf)") - def routerDispatcher: String = Dispatchers.DefaultDispatcherId - def supervisorStrategy: SupervisorStrategy = Router.defaultSupervisorStrategy +case object FromConfig extends FromConfig { + def instance = this + def apply(routerDispatcher: String = Dispatchers.DefaultDispatcherId) = new FromConfig(routerDispatcher) + def unapply(fc: FromConfig): Option[String] = Some(fc.routerDispatcher) } /** @@ -389,7 +395,11 @@ case object FromConfig extends RouterConfig { * (defaults to default-dispatcher). */ //TODO add @SerialVersionUID(1L) when SI-4804 is fixed -case class FromConfig(val routerDispatcher: String = Dispatchers.DefaultDispatcherId) extends RouterConfig { +class FromConfig(val routerDispatcher: String = Dispatchers.DefaultDispatcherId) + extends RouterConfig + with Product + with Serializable + with Equals { def this() = this(Dispatchers.DefaultDispatcherId) @@ -397,6 +407,31 @@ case class FromConfig(val routerDispatcher: String = Dispatchers.DefaultDispatch throw new ConfigurationException("router " + routeeProvider.context.self + " needs external configuration from file (e.g. application.conf)") def supervisorStrategy: SupervisorStrategy = Router.defaultSupervisorStrategy + + // open-coded case class to preserve binary compatibility, all deprecated for 2.1 + @deprecated("FromConfig does not make sense as case class", "2.0.1") + override def productPrefix = "FromConfig" + @deprecated("FromConfig does not make sense as case class", "2.0.1") + def productArity = 1 + @deprecated("FromConfig does not make sense as case class", "2.0.1") + def productElement(x: Int) = x match { + case 0 ⇒ routerDispatcher + case _ ⇒ throw new IndexOutOfBoundsException(x.toString) + } + @deprecated("FromConfig does not make sense as case class", "2.0.1") + def copy(d: String = Dispatchers.DefaultDispatcherId): FromConfig = new FromConfig(d) + @deprecated("FromConfig does not make sense as case class", "2.0.1") + def canEqual(o: Any) = o.isInstanceOf[FromConfig] + @deprecated("FromConfig does not make sense as case class", "2.0.1") + override def hashCode = ScalaRunTime._hashCode(this) + @deprecated("FromConfig does not make sense as case class", "2.0.1") + override def toString = "FromConfig(" + routerDispatcher + ")" + @deprecated("FromConfig does not make sense as case class", "2.0.1") + override def equals(other: Any): Boolean = other match { + case FromConfig(x) ⇒ x == routerDispatcher + case _ ⇒ false + } + } object RoundRobinRouter { diff --git a/akka-zeromq/src/main/scala/akka/zeromq/Response.scala b/akka-zeromq/src/main/scala/akka/zeromq/Response.scala index e9ef273397..2729e582b3 100644 --- a/akka-zeromq/src/main/scala/akka/zeromq/Response.scala +++ b/akka-zeromq/src/main/scala/akka/zeromq/Response.scala @@ -11,8 +11,12 @@ sealed trait Response /** * When the ZeroMQ socket connects it sends this message to a listener */ -case object Connecting extends Response +case object Connecting extends Response { + def instance = this +} /** * When the ZeroMQ socket disconnects it sends this message to a listener */ -case object Closed extends Response +case object Closed extends Response { + def instance = this +}