kotlinktor

Ktor error: Neither port nor sslPort specified


So, I've read numerous answers on how to resolve this error, but it doesn't seem to apply to my situation.

This is a ktor application, built with maven.

I'm getting the error: Exception in thread "main" java.lang.IllegalArgumentException: Neither port nor sslPort specified. Use command line options -port/-sslPort or configure connectors in application.conf

First of all, my application runs fine in IntelliJ Ultimate, but fails when I try to run the fatjar on the commandline like this: java -jar target/myApp-jar-with-dependencies.jar

The crux of the matter seems to be that I'm having my configuration in an application.yaml file.

I've included this dependency:

    <dependency>
        <groupId>io.ktor</groupId>
        <artifactId>ktor-server-config-yaml-jvm</artifactId>
        <version>${ktor_version}</version>
    </dependency>

My application structure looks like this:

enter image description here

When I create an application.conf in the same folder it works fine, which indicates that it just does not expect a yaml configuration file, even when I've included the ktor yaml dependency.

Lastly, my maven build segment looks like this:

 <build>
    <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
    <resources>
        <resource>
            <directory>${project.basedir}/src/main/resources</directory>
        </resource>
    </resources>

    <plugins>
        <plugin>
            <artifactId>kotlin-maven-plugin</artifactId>
            <groupId>org.jetbrains.kotlin</groupId>
            <version>${kotlin_version}</version>
            <configuration>
                <jvmTarget>17</jvmTarget>
                <compilerPlugins>
                    <plugin>kotlinx-serialization</plugin>
                </compilerPlugins>
            </configuration>
            <executions>
                <execution>
                    <id>compile</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.jetbrains.kotlin</groupId>
                    <artifactId>kotlin-maven-serialization</artifactId>
                    <version>${kotlin_version}</version>
                </dependency>
            </dependencies>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <execution>
                    <goals>
                        <goal>java</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mainClass>${main.class}</mainClass>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <mainClass>${main.class}</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>assemble-all</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Any help would be appreciated.


Solution

  • Ktor uses the ServiceLoader to load all the available config loaders and then tries to load the default configuration with each. The HoconConfigLoader is defined in the ktor-server-core-jvm module, and the YamlConfigLoader is defined in the ktor-server-config-yaml-jvm module. As far as I understand, the assembly Maven plugin takes the META-INF/services/io.ktor.server.config.ConfigLoader file of the first package containing that file and packages it in the result JAR.

    Since the ktor-server-core-jvm module goes first in the dependencies block in the pom.xml, the plugin packages only a definition of the HoconConfigLoader and ignores the one for YAML. As a result, the application only tries to load the application.conf file, which doesn't exist.

    To solve the problem, switch the order of the dependencies in the pom.xml file:

    <dependencies>
        <dependency> <!-- To be able to use yaml as server configuration -->
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-config-yaml-jvm</artifactId>
            <version>${ktor_version}</version>
        </dependency>
        <!-- Ktor -->
        <dependency>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-core-jvm</artifactId>
            <version>${ktor_version}</version>
        </dependency>
    <!-- ... -->
    <dependencies>