Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IntelliJ Maven Projects are not working #125

Open
krisutofu opened this issue Jun 21, 2023 · 2 comments
Open

IntelliJ Maven Projects are not working #125

krisutofu opened this issue Jun 21, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@krisutofu
Copy link

krisutofu commented Jun 21, 2023

Not sure whether this is a bug or an enhancement.

Problem description

It seems, that in some cases people use Kotlin with Maven and export it from IntelliJ. This is the case for study homework at university. But it seems, it doesn't work by default. The pom.xml file is incomplete and maven commands or the launch configuration don't work.

Extension version

I am running the latest available version in the marketplace that is tagged as "preview".

How to fix it

It took me a lot of time but I figured out how to edit the pom.xml to make it run. This is what needs to be in the pom.xml to run.

Required dependencies (stdlib and testing):

        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-test-junit</artifactId>
            <version>${kotlin.version}</version>
            <scope>test</scope>
        </dependency>

Required build elements (these were missing as well!):

  • <sourceDirectory>src/main/kotlin</sourceDirectory> (the main source directory, could also be src/main/java or src/main/resources or sthg. like that)
  • <testSourceDirectory>src/test/kotlin</testSourceDirectory> (same as before but with test instead of main)

Required plugins (Kotlin compilation, Maven assembly):

<plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <configuration>
                    <jvmTarget>${java.version}</jvmTarget>
                </configuration>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals> <goal>compile</goal> </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
                                <sourceDir>${project.basedir}/src/main/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals> <goal>single</goal> </goals>
                        <configuration>
                            <archive>
                                <manifest>
                                    <mainClass>${main.class}</mainClass>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Optional plugin (Java compilation, for mixed projects):

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
                <executions>
                    <!-- Replacing default-compile as it is treated specially by maven -->
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                    <!-- Replacing default-testCompile as it is treated specially by maven -->
                    <execution>
                        <id>default-testCompile</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>java-compile</id>
                        <phase>compile</phase>
                        <goals> <goal>compile</goal> </goals>
                    </execution>
                    <execution>
                        <id>java-test-compile</id>
                        <phase>test-compile</phase>
                        <goals> <goal>testCompile</goal> </goals>
                    </execution>
                </executions>
            </plugin>

Optional, these are the properties I use:

  • java.version
  • <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  • <kotlin.version>1.8.22</kotlin.version> (a new one as of this writing)
  • kotlin.compiler.jvmTarget
  • main.class
  • junit.version

If one of these things is missing, it's likely that the project won't run.

MainKt ClassNotFoundException

This happens sometimes because some Maven plugin (or whatever it is) puts Kotlin Source files in the classpath ./target/classes and puts all compiled .class files in some other path ./target/kotlin-ic/compile/classes.

If then the Kotlin-Launcher tries to execute the application, given the main class, it won't find it. I also noticed that the Kotlin-specific classes directory is sometimes flattened, sometimes not, which also led to ClassNotFoundExceptions on startup, because the classes were not in the right directory.

I wrote a simple bash script that copies all classes to the correct classpath location:

#!/bin/bash

fromDir="./target/kotlin-ic/compile/classes"
classpath="./target/classes"

for kotlinFile in $(find ${classpath} -name "*.kt")
do
	destinationDirectory="$(dirname "${kotlinFile}")"
	fromDirectory="${fromDir}/${destinationDirectory#${classpath}/}"
	for className in $(grep -P '(?<=\bclass )[A-Z]\w*' "${fromDirectory}" --no-filename --only-matching) "$(basename "${kotlinFile%.*}")"
	do
		cp -t "${destinationDirectory}" $(find "${fromDirectory}" -name "${className}*.class")
	done
done

[I edited the script to copy rather than to move the files. It otherwise makes problems with incremental builds.]

@krisutofu krisutofu added the bug Something isn't working label Jun 21, 2023
@themkat
Copy link
Contributor

themkat commented Jun 21, 2023

A lot of what you mention that needs to be added is simply standard Kotlin setup for Maven. I'm surprised that IntelliJ does not export them. Does the project even compile with mvn clean install without adding it?!? 😱

This is probably also not a VSCode extension issue, but a language server issue. @fwcd , maybe we could move it?

@krisutofu
Copy link
Author

krisutofu commented Jun 21, 2023

A lot of what you mention that needs to be added is simply standard Kotlin setup for Maven. I'm surprised that IntelliJ does not export them. Does the project even compile with mvn clean install without adding it?!? scream

This is probably also not a VSCode extension issue, but a language server issue. @fwcd , maybe we could move it?

Yes, I am surprised too. I redownloaded our provided project, unzipped it into a new folder, opened that one in VSCode and then tried mvn clean install as you said but it causes a build failure after all after downloading 43MiB of stuff.

The literal pom.xml structure which we obtained for our project is this:

<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>{{…}}</groupId>
    <artifactId>{{…}}</artifactId>
    <version>{{…}}</version>
    <packaging>jar</packaging>
    <description>{{… Exercise …}}</description>

    <properties>
        <java.version>11</java.version>
        <kotlin.version>1.3.72</kotlin.version>
        <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
    </properties>

    <dependencies>
        <dependency>
            <groupId>{{… their group name …}}</groupId>
            <artifactId>{{… their framework name …}}</artifactId>
            <version>{{…}}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <configuration>
                    <jvmTarget>${java.version}</jvmTarget>
                </configuration>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals> <goal>compile</goal> </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
                                <sourceDir>${project.basedir}/src/main/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
                <executions>
                    <!-- Replacing default-compile as it is treated specially by maven -->
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                    <!-- Replacing default-testCompile as it is treated specially by maven -->
                    <execution>
                        <id>default-testCompile</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>java-compile</id>
                        <phase>compile</phase>
                        <goals> <goal>compile</goal> </goals>
                    </execution>
                    <execution>
                        <id>java-test-compile</id>
                        <phase>test-compile</phase>
                        <goals> <goal>testCompile</goal> </goals>
                    </execution>
                </executions>
            </plugin>
            
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals> <goal>single</goal> </goals>
                        <configuration>
                            <archive>
                                <manifest>
                                    <mainClass>{{… MainKt here …}}</mainClass>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>    

    <repositories>
		<repository>
			<id>{{…}}</id>
			<name>{{… their open repo name …}}</name>
			<url>{{…}}</url>
		</repository>
        <repository>
            <id>gradle-m2</id>
            <name>gradle-m2</name>
            <url>https://plugins.gradle.org/m2/</url>
        </repository>
        <repository>
            <id>kotlin-eap</id>
            <name>kotlin-eap</name>
            <url>https://dl.bintray.com/kotlin/kotlin-eap/</url>
        </repository>
        <repository>
            <id>kotlin-native</id>
            <name>kotlin-native</name>
            <url>https://dl.bintray.com/jetbrains/kotlin-native-dependencies/</url>
        </repository>
    </repositories>

</project>

I do not even know why there is a Gradle repo when they use Maven. The pom.xml is manually edited at one place where they inserted their own repository element (indentation is awry).

Apparently, this project just works when importing it into IntelliJ (and I think, this has been their recommended IDE) but I don't know other people from my course who got this running in VSCode. All my team mates switched because they didn't get it running. Then I compared the given pom.xml against a Kotlin-Maven tutorial, from scratch, and added all the missing elements. That worked. My team mates did the first homework in IntelliJ.

Note that I even inserted that <phase>compile</phase> element inside the Kotlin-maven-plugin by myself.

I also created some nice launch.json and tasks.json config files for running the project. But this is rather a feature request, to have some standard tasks being generated right away for maven projects. I currently copy them from project to project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants