简体   繁体   中英

No configuration setting found for key 'akka.version'

I am learning akka-remoting and this is how my project looks

The project structure looks like

project/pom.xml
project/mymodule/pom.xml
project/mymodule/src/main/resources/application.conf
project/mymodule/src/main/scala/com.harit.akkaio.remote.RemoteApp.scala
project/mymodule/src/main/scala/com.harit.akkaio.remote.ProcessingActor.scala

When I run my project on command-line , I see

$ java -jar akkaio-remote/target/akka-remote-jar-with-dependencies.jar com.harit.akkaio.remote.RemoteApp
Hello:com.harit.akkaio.remote.RemoteApp
Exception in thread "main" com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'akka.version'
    at com.typesafe.config.impl.SimpleConfig.findKey(SimpleConfig.java:124)
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:145)
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:151)
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:159)
    at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:164)
    at com.typesafe.config.impl.SimpleConfig.getString(SimpleConfig.java:206)
    at akka.actor.ActorSystem$Settings.<init>(ActorSystem.scala:169)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:505)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:142)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:119)
    at com.harit.akkaio.remote.RemoteApp$.startProcessingActorSystem(RemoteApp.scala:16)
    at com.harit.akkaio.remote.RemoteApp$.main(RemoteApp.scala:12)
    at com.harit.akkaio.remote.RemoteApp.main(RemoteApp.scala)

RemoteApp.scala

package com.harit.akkaio.remote

import akka.actor.{ActorRef, ActorSystem, Props}
import com.typesafe.config.ConfigFactory

import scala.concurrent.duration._

object RemoteApp {
  def main(args: Array[String]): Unit = {
    println("Hello:" + args.head)
      startProcessingActorSystem()
  }

  def startProcessingActorSystem() = {
    val system = ActorSystem("ProcessingSystem", ConfigFactory.load())
    println("ProcessingActorSystem Started")
  }
}

ProcessingActor.scala

package com.harit.akkaio.remote

import akka.actor.{Actor, ActorLogging}

case object Process

case object Crash

class ProcessingActor extends Actor with ActorLogging {
  def receive = {
    case Process => log.info("processing big things")
    case Crash => log.info("crashing the system")
      context.stop(self)
  }
}

application.conf

akka {
  remote.netty.tcp.port = 2552
}

mymodule.pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>akkaio</artifactId>
        <groupId>com.harit</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>akkaio-remote</artifactId>

    <properties>
        <akka-remote_2.11.version>2.3.11</akka-remote_2.11.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-remote_2.11</artifactId>
            <version>${akka-remote_2.11.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <finalName>akka-remote</finalName>
                    <archive>
                        <manifest>
                            <mainClass>com.harit.akkaio.remote.RemoteApp</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id> <!-- this is used for inheritance merges -->
                        <phase>package</phase> <!-- bind to the packaging phase -->
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.harit</groupId>
    <artifactId>akkaio</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>akkaio-remote</module>
    </modules>

    <packaging>pom</packaging>
    <inceptionYear>2015</inceptionYear>
    <properties>
        <scala.version>2.11.6</scala.version>
        <junit.version>4.12</junit.version>
        <scalatest_2.11.version>2.2.5</scalatest_2.11.version>
        <akka-actor_2.11.version>2.3.11</akka-actor_2.11.version>
        <akka-slf4j_2.11.version>2.3.11</akka-slf4j_2.11.version>
        <akka-testkit_2.11.version>2.3.11</akka-testkit_2.11.version>
        <mockito-all.version>1.10.19</mockito-all.version>
        <maven-scala-plugin.scalaCompatVersion>2.11.6</maven-scala-plugin.scalaCompatVersion>
        <scalatest-maven-plugin.version>1.0</scalatest-maven-plugin.version>
    </properties>

    <repositories>
        <repository>
            <id>scala-tools.org</id>
            <name>Scala-Tools Maven2 Repository</name>
            <url>http://scala-tools.org/repo-releases</url>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>scala-tools.org</id>
            <name>Scala-Tools Maven2 Repository</name>
            <url>http://scala-tools.org/repo-releases</url>
        </pluginRepository>
    </pluginRepositories>

    <dependencies>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-actor_2.11</artifactId>
            <version>${akka-actor_2.11.version}</version>
        </dependency>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-slf4j_2.11</artifactId>
            <version>${akka-slf4j_2.11.version}</version>
        </dependency>
        <dependency>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest-maven-plugin</artifactId>
            <version>${scalatest-maven-plugin.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.typesafe.akka</groupId>
            <artifactId>akka-testkit_2.11</artifactId>
            <version>${akka-testkit_2.11.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.scalatest</groupId>
            <artifactId>scalatest_2.11</artifactId>
            <version>${scalatest_2.11.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>clean install</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <scalaCompatVersion>${maven-scala-plugin.scalaCompatVersion}</scalaCompatVersion>
                    <scalaVersion>${scala.version}</scalaVersion>
                    <scalaVersion>${scala.version}</scalaVersion>
                    <args>
                        <arg>-target:jvm-1.8</arg>
                    </args>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.7</version>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.scalatest</groupId>
                <artifactId>scalatest-maven-plugin</artifactId>
                <version>1.0</version>
                <configuration>
                    <reportsDirectory>${project.build.directory}/surefire-reports</reportsDirectory>
                    <junitxml>.</junitxml>
                    <filereports>WDF TestSuite.txt</filereports>
                </configuration>
                <executions>
                    <execution>
                        <id>test</id>
                        <goals>
                            <goal>test</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <reporting>
        <plugins>
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <configuration>
                    <scalaVersion>${scala.version}</scalaVersion>
                </configuration>
            </plugin>
        </plugins>
    </reporting>
</project>

What am I missing out? Thanks

It seems that your problem is bundling into a jar-with-dependencies , which causes problems with Akka, as described in the documentation :

Warning

Akka's configuration approach relies heavily on the notion of every module/jar having its own reference.conf file, all of these will be discovered by the configuration and loaded. Unfortunately this also means that if you put/merge multiple jars into the same jar, you need to merge all the reference.confs as well. Otherwise all defaults will be lost and Akka will not function.

As suggested on the same page, you can use maven-shade-plugin to merge all the reference configurations:

If you are using Maven to package your application, you can also make use of the Apache Maven Shade Plugin support for Resource Transformers to merge all the reference.confs on the build classpath into one.

See also: Akka: missing akka.version

Had a similar issue:

com.typesafe.config.ConfigException$Missing: 
No configuration setting found for key 'akka.persistence.journal-plugin-fallback'

Solved it with adding an appending transformer:

<plugin>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.4.1</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <transformers>
          <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
            <resource>reference.conf</resource>
          </transformer>
        </transformers>
      </configuration>
    </execution>
  </executions>
</plugin>

So the problem generates while making a fat jar but not handling reference.conf the right way.

The explanation follows from @Zoltan's answer:

It seems that your problem is bundling into a jar-with-dependencies, which causes problems with Akka, as described in the documentation:

Warning

Akka's configuration approach relies heavily on the notion of every module/jar having its own reference.conf file, all of these will be discovered by the configuration and loaded. Unfortunately this also means that if you put/merge multiple jars into the same jar, you need to merge all the reference.confs as well. Otherwise all defaults will be lost and Akka will not function.

I have a solution for SBT users which doesn't require a plugin.

In build.sbt, add case "reference.conf" => MergeStrategy.concat to your module assembly configuration.

lazy val module_name = (project in file("module_path"))
  .settings(
    name := "module_name",
    commonSettings,
    assemblyJarName in assembly := "module_name.jar",
    test in assembly := {},
    assemblyMergeStrategy in assembly := {
      case PathList("META-INF", xs @ _*) => MergeStrategy.discard

    #################### The line which needs to be added ###################
      case "reference.conf" => MergeStrategy.concat
      case _ => MergeStrategy.first
    }
  )
  .dependsOn(other_modules, other_modules2)

The command MergeStrategy.concat literally functions the same way. While assembling whenever it encounters reference.conf it concatenates it to instead of creating a separate file for each akka module (which is the default behaviour).

Someone experienced on working with maven(pom.xml), please! extend this answer.

a lot of the submitted answers are suggesting a generic solution for setting up a merge strategy for concatenating the default typesafe config file (aka reference.conf).

That will not necessarily work for Akka libraries as Akka has some of its configurations included into the reference.conf from other files. That includes the akka.version property that lives in a version.conf file.

####################################
# Akka Actor Reference Config File #
####################################

# This is the reference config file that contains all the default settings.
# Make your edits/overrides in your application.conf.

# Akka version, checked against the runtime version of Akka. Loaded from generated conf file.
include "version"

So for an akka library you may need to include that file with a concat merge strategy in addition to the reference.conf strategy as other third party libraries may be doing something similar

assemblyMergeStrategy in assembly := {
  case PathList("META-INF", "MANIFEST.MF") => 
    val log = sLog.value
    log.info("discarding MANIFEST.MF")
    MergeStrategy.discard
  case PathList("reference.conf") => 
    val log = sLog.value
    log.info("concatinating reference.conf")
    MergeStrategy.concat
  case PathList("version.conf") => 
    val log = sLog.value
    log.info("concatinating version.conf")
    MergeStrategy.concat
  case default => 
    val log = sLog.value
    log.debug(s"keeping last $default")
    MergeStrategy.last    
}

this is a common problem with alpakka as the version.conf in your uber jar will need to be concated to contain values from both libs. So the version.conf in your uber jar would need to look something like this:

akka.version = "2.6.19"
akka.kafka.version = "2.0.7"

(my solution is using scala / sbt and its assembly plugin, but you can do something similar for java / maven)

Adding AppendingTransformer alone didn't resolve the issue for me. If you are trying to deploy your spark application on EMR and are still facing this issue then please take a look at my solution here . Hope it helps!

Add the following plug-ins:

<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-shade-plugin</artifactId>
 <version>1.5</version>
 <executions>
  <execution>
   <phase>package</phase>
   <goals>
    <goal>shade</goal>
   </goals>
   <configuration>
    <shadedArtifactAttached>true</shadedArtifactAttached>
    <shadedClassifierName>allinone</shadedClassifierName>
    <artifactSet>
     <includes>
      <include>*:*</include>
     </includes>
    </artifactSet>
    <transformers>
      <transformer
       implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
       <resource>reference.conf</resource>
      </transformer>
      <transformer
       implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
       <manifestEntries>
        <Main-Class>akka.Main</Main-Class>
       </manifestEntries>
      </transformer>
    </transformers>
   </configuration>
  </execution>
 </executions>
</plugin>

Reference here:akka—docsenter link description here

I tried this plugin, it is great but leads to another error due to some signed jars. Here is the error:

Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

What I would suggest you to use is the spring boot maven plugin. Just add it to your build and enjoy seamless runnable jars. This is one good reason why I love Spring framework.

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
            <configuration>
                <classifier>final</classifier>
                <mainClass>
                    com.main.PopularHashTags
                </mainClass>
            </configuration>
        </execution>
    </executions>
</plugin>

Note: You don't need to have a Spring Boot application to use this plugin. Just use it in any application and it works as a charm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM