Hi Bruce,
10 apr 2014 kl. 19:26 skrev Bruce <[email protected]>:
> Hi,
>
> I have an issue related to ports when trying to remote (Scala 2.10.4, Akka
> 2.3.1). This is stripped down code that doesn't actually do anything
> remotely itself. When I set the port to 0 in the application.conf file, it
> finds a free port and works without throwing an exception, shown here as the
> result of running lsof -i -n -P
>
> com.apple 3205 username 10u IPv4 0xdcc81blahblah 0t0 UDP *:*
> java 4739 username 61u IPv6 0xdcc81blahblah 0t0 TCP
> 127.0.0.1:57230 (LISTEN)
> java 4739 username 63u IPv6 0xdcc81blahblah 0t0 TCP
> [::1]:57229->[::1]:57228 (FIN_WAIT_1)
> java 4739 username 81u IPv6 0xdcc81blahblah 0t0 TCP
> 127.0.0.1:57231 (LISTEN)
>
> If I then manually code the assigned port into my worker code (not included),
> I can send a message to the master and receive it no problem. However, when
> I set the port to 2552, it throws a java.net.BindException: Address already
> in use. My question is, why is it throwing this exception when the port
> wasn't bound prior to running the app? It appears that the process itself is
> what's binding the port, as shown in the following.
>
> com.apple 3205 username 10u IPv4 0xdcc81blahblah 0t0 UDP *:*
> java 4772 username 61u IPv6 0xdcc81blahblah 0t0 TCP
> 127.0.0.1:2552 (LISTEN)
> java 4772 username 63u IPv6 0xdcc81blahblah 0t0 TCP
> [::1]:57237->[::1]:57236 (FIN_WAIT_1)
>
> If I try to set the port in the application.conf file to what was previously
> assigned when setting the port to 0, I get the same behaviour as when I try
> to set it to 2552. I get exactly the same behaviour regardless of whether I
> run this on my MacBook Pro Retina or Linux Server.
>
> The code:
>
> import akka.actor._
> import akka.actor.SupervisorStrategy._
> import scala.concurrent.duration._
> import com.typesafe.config._
> import scala.util._
> import akka.event.Logging
>
> class RemoteMaster() extends Actor {
> import context.dispatcher
>
> def receive = {
> case str:String => println("Message is " + str)
> case msg => println("RemoteMaster: Unhandled Message" + msg)
> }
> }
>
> object RemoteMaster {
> val config = ConfigFactory.load()
> val system = ActorSystem("system", config)
ActorSystem #1
> val log = Logging(system.eventStream, "blah.remote.main")
>
> def main(args:Array[String]) {
> val config = ConfigFactory.load()
> val system = ActorSystem("system", config)
ActorSystem #2
Using the same configuration they will clash in the way you observe.
Now you might propose that Akka should see this and report it in a more direct
fashion, but unfortunately that would require global shared mutable state in
the JVM, which is something that we strictly avoid.
Regards,
Roland
> val listener = system.actorOf(Props(new RemoteMaster),"rm")
> system.eventStream.subscribe(listener, classOf[DeadLetter])
> system.actorSelection("akka://system/user/rm") ! "Test"
> }
> }
>
> The application.conf:
>
> akka {
> # Akka version, checked against the runtime version of Akka.
> version = "2.3.1" # for regular use
> # Event handlers to register at boot time (Logging$DefaultLogger logs to
> STDOUT)
> event-handlers = ["akka.event.slf4j.Slf4jLogger"]
> # Log level used by the configured loggers (see "event-handlers") as soon
> # Options: ERROR, WARNING, INFO, DEBUG
> loglevel = "INFO"
>
> # Log level for the very basic logger activated during AkkaApplication
> startup
> # Options: ERROR, WARNING, INFO, DEBUG
> stdout-loglevel = "ERROR"
> actor {
> provider = "akka.remote.RemoteActorRefProvider"
> }
> remote {
> enabled-transports = ["akka.remote.netty.tcp"]
> netty.tcp {
> hostname = "127.0.0.1"
> port = 2552
> # port = 0
> }
> }
> }
>
> Build.scala (ugly as hell):
>
> import sbt._
> import sbt.Keys._
> import sbtassembly.Plugin._
> import AssemblyKeys._
> object ProjectBuild extends Build {
> val useConsole = SettingKey[Boolean]("use-console")
> val jvmOptions = Seq("-server","-Xms2g","-Xmx4g")
> lazy val root = Project(
> id = "Remote",
> base = file("."),
> settings = Project.defaultSettings ++ assemblySettings ++ Seq(
> name := "Remote",
> organization := "com.epoch6",
> scalaVersion := "2.10.4",
> scalacOptions ++= Seq( "-deprecation","-feature"),
> // run fork settings
> fork in run := true,
> javaOptions in run := jvmOptions,
> mainClass in (Compile, run) := Some("com.epoch6.remote.RemoteMaster"),
> testOptions += Tests.Setup( cl =>
> cl.loadClass("org.slf4j.LoggerFactory").
> getMethod("getLogger",cl.loadClass("java.lang.String")).
> invoke(null,"ROOT")
> ),
> // akka and atmos settings
> useConsole := false,
> credentials += Credentials(Path.userHome / "atmos.credentials"),
> resolvers += "Typesafe Repo" at
> "http://repo.typesafe.com/typesafe/releases/",
> resolvers += "Sonatype shapshot repo" at
> "https://oss.sonatype.org/content/repositories/snapshots/",
> libraryDependencies <++= useConsole { Dependencies.akka },
> ivyXML <<= useConsole { Dependencies.excludes },
> // library dependencies
> libraryDependencies ++= Dependencies.dependencies,
> // Fat jar settings
> jarName in assembly := "Remote.jar",
> test in assembly := {},
> mainClass in assembly := Some("com.epoch6.remote.RemoteMaster")
> )
> )
> }
> object Dependencies {
> object V {
> val Akka = "2.3.1"
> }
> val akkaSlf4j = "com.typesafe.akka" %% "akka-slf4j" % V.Akka
> val akkaTestkit = "com.typesafe.akka" %% "akka-testkit" % V.Akka
> val akkaActor = "com.typesafe.akka" %% "akka-actor" % V.Akka
> val akkaRemote = "com.typesafe.akka" %% "akka-remote" % V.Akka
> val akkaCluster = "com.typesafe.akka" %% "akka-cluster" % V.Akka
>
> val originalAkka = Seq(akkaSlf4j, akkaTestkit, akkaActor, akkaRemote,
> akkaCluster)
> val dependencies = Seq(
> "joda-time" % "joda-time" % "1.6.2",
> "org.scalatest" % "scalatest_2.10" % "2.0.M8",
> "org.scalacheck" %% "scalacheck" % "1.10.1" % "test",
> "ch.qos.logback" % "logback-classic" % "1.0.7"
> )
> val normalExcludes = {
> <dependencies>
> </dependencies>
> }
> def akka(atmos: Boolean) = originalAkka
> def excludes(atmos: Boolean) = normalExcludes
> }
>
> The output when port set to 0:
>
> sbt run
> [info] Loading project definition from
> /Users/username/projects/Remote/project/project
> [info] Loading project definition from /Users/username/projects/Remote/project
> [info] Set current project to Remote (in build
> file:/Users/username/projects/Remote/)
> [info] Running com.epoch6.remote.RemoteMaster
> [info] [INFO] [04/10/2014 14:18:51.535] [main] [Remoting] Starting remoting
> [info] [INFO] [04/10/2014 14:18:51.691] [main] [Remoting] Remoting started;
> listening on addresses :[akka.tcp://[email protected]:59083]
> [info] [INFO] [04/10/2014 14:18:51.692] [main] [Remoting] Remoting now
> listens on addresses: [akka.tcp://[email protected]:59083]
> [info] [INFO] [04/10/2014 14:18:51.718] [main] [Remoting] Starting remoting
> [info] [INFO] [04/10/2014 14:18:51.727] [main] [Remoting] Remoting started;
> listening on addresses :[akka.tcp://[email protected]:59084]
> [info] [INFO] [04/10/2014 14:18:51.727] [main] [Remoting] Remoting now
> listens on addresses: [akka.tcp://[email protected]:59084]
> [info] Message is Test
>
> The exception thrown when port set to 2552:
>
> [info] Loading project definition from
> /Users/username/projects/Remote/project/project
> [info] Loading project definition from /Users/username/projects/Remote/project
> [info] Set current project to Remote (in build
> file:/Users/username/projects/Remote/)
> [info] Running com.epoch6.remote.RemoteMaster
> [info] [INFO] [04/10/2014 14:05:02.449] [main] [Remoting] Starting remoting
> [info] [INFO] [04/10/2014 14:05:02.610] [main] [Remoting] Remoting started;
> listening on addresses :[akka.tcp://[email protected]:2552]
> [info] [INFO] [04/10/2014 14:05:02.611] [main] [Remoting] Remoting now
> listens on addresses: [akka.tcp://[email protected]:2552]
> [info] [INFO] [04/10/2014 14:05:02.637] [main] [Remoting] Starting remoting
> [error] Exception in thread "main" org.jboss.netty.channel.ChannelException:
> Failed to bind to: /127.0.0.1:2552
> [error] at
> org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:272)
> [error] at
> akka.remote.transport.netty.NettyTransport$$anonfun$listen$1.apply(NettyTransport.scala:392)
> [info] [ERROR] [04/10/2014 14:05:02.649] [main] [Remoting] Remoting error:
> [Startup failed] [
> [error] at
> akka.remote.transport.netty.NettyTransport$$anonfun$listen$1.apply(NettyTransport.scala:389)
> [error] at scala.util.Success$$anonfun$map$1.apply(Try.scala:206)
> [info] akka.remote.RemoteTransportException: Startup failed
> [error] at scala.util.Try$.apply(Try.scala:161)
> [info] at
> akka.remote.Remoting.akka$remote$Remoting$$notifyError(Remoting.scala:128)
> [info] at akka.remote.Remoting.start(Remoting.scala:193)
> [error] at scala.util.Success.map(Try.scala:206)
> [info] at
> akka.remote.RemoteActorRefProvider.init(RemoteActorRefProvider.scala:184)
> [error] at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:235)
> [info] at akka.actor.ActorSystemImpl.liftedTree2$1(ActorSystem.scala:617)
> [error] at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:235)
> [info] at akka.actor.ActorSystemImpl._start$lzycompute(ActorSystem.scala:615)
> [error] at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
> [info] at akka.actor.ActorSystemImpl._start(ActorSystem.scala:615)
> [error] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:67)
> [info] at akka.actor.ActorSystemImpl.start(ActorSystem.scala:632)
> [error] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:82)
> [info] at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
> [error] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:59)
> [info] at akka.actor.ActorSystem$.apply(ActorSystem.scala:118)
> [error] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:59)
> [info] at com.epoch6.remote.RemoteMaster$.main(RemoteMaster.scala:28)
> [info] at com.epoch6.remote.RemoteMaster.main(RemoteMaster.scala)
> [error] at
> scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:72)
> [error] at akka.dispatch.BatchingExecutor$Batch.run(BatchingExecutor.scala:58)
> [info] Caused by: org.jboss.netty.channel.ChannelException: Failed to bind
> to: /127.0.0.1:2552
> [error] at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
> [info] at
> org.jboss.netty.bootstrap.ServerBootstrap.bind(ServerBootstrap.java:272)
> [error] at
> akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
> [info] at
> akka.remote.transport.netty.NettyTransport$$anonfun$listen$1.apply(NettyTransport.scala:392)
> [error] at
> scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
> [info] at
> akka.remote.transport.netty.NettyTransport$$anonfun$listen$1.apply(NettyTransport.scala:389)
> [error] at
> scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
> [info] at scala.util.Success$$anonfun$map$1.apply(Try.scala:206)
> [error] at
> scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
> [info] at scala.util.Try$.apply(Try.scala:161)
> [error] at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
> [info] at scala.util.Success.map(Try.scala:206)
> [error] Caused by: java.net.BindException: Address already in use
> [info] at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:235)
> [error] at sun.nio.ch.Net.bind(Native Method)
> [error] at
> sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:124)
> [error] at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)
> [info] at scala.concurrent.Future$$anonfun$map$1.apply(Future.scala:235)
> [info] at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
> [error] at
> org.jboss.netty.channel.socket.nio.NioServerBoss$RegisterTask.run(NioServerBoss.java:193)
> [info] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.processBatch$1(BatchingExecutor.scala:67)
> [error] at
> org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:372)
> [info] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply$mcV$sp(BatchingExecutor.scala:82)
> [error] at
> org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:296)
> [info] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:59)
> [error] at
> org.jboss.netty.channel.socket.nio.NioServerBoss.run(NioServerBoss.java:42)
> [info] at
> akka.dispatch.BatchingExecutor$Batch$$anonfun$run$1.apply(BatchingExecutor.scala:59)
> [error] at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
> [info] at
> scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:72)
> [error] at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
> [info] at akka.dispatch.BatchingExecutor$Batch.run(BatchingExecutor.scala:58)
> [error] at java.lang.Thread.run(Thread.java:695)
> [info] at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:41)
> [info] at
> akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
> [info] at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
> [info] at
> scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
> [info] at
> scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
> [info] at
> scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
> [info] Caused by: java.net.BindException: Address already in use
> [info] at sun.nio.ch.Net.bind(Native Method)
> [info] at
> sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:124)
> [info] at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:59)
> [info] at
> org.jboss.netty.channel.socket.nio.NioServerBoss$RegisterTask.run(NioServerBoss.java:193)
> [info] at
> org.jboss.netty.channel.socket.nio.AbstractNioSelector.processTaskQueue(AbstractNioSelector.java:372)
> [info] at
> org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:296)
> [info] at
> org.jboss.netty.channel.socket.nio.NioServerBoss.run(NioServerBoss.java:42)
> [info] at
> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
> [info] at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
> [info] at java.lang.Thread.run(Thread.java:695)
> [info] ]
> [info] [INFO] [04/10/2014 14:05:02.655]
> [system-akka.remote.default-remote-dispatcher-7]
> [akka://system/system/remoting-terminator] Shutting down remote daemon.
> [info] [INFO] [04/10/2014 14:05:02.656]
> [system-akka.remote.default-remote-dispatcher-7]
> [akka://system/system/remoting-terminator] Remote daemon shut down;
> proceeding with flushing remote transports.
> [info] [INFO] [04/10/2014 14:05:02.662] [ForkJoinPool-5-worker-15] [Remoting]
> Remoting shut down
> [info] [INFO] [04/10/2014 14:05:02.662]
> [system-akka.remote.default-remote-dispatcher-6]
> [akka://system/system/remoting-terminator] Remoting shut down.
> Thanks,
> Bruce
>
> --
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ:
> >>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ:
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.