Kotlin: How to import a class from another IntelliJ module? - intellij-idea

I have a simple Kotlin project in IntelliJ with two modules defined as sub-folders under the project root folder. Everything seems to be set up correctly in build settings, each module has its own folder marked as a source directory.
I can run main functions in both modules so IntelliJ is finding everything OK.
What I cannot do is reference a public class in one module in the other. I've tried every form of import statement I can think of, but the compiler always flags the class in module1 as an unresolved reference in module2.

Related

How build EXE from TornadoFX JAR?

I have a simple JavaFX/TornadoFX project on Windows that builds in a JAR and runs correctly from under IntelliJ IDEA and in the JRE installed on my computer. I want to make it so that this project can run on any Windows machine without JRE installed. To do this, in IntelliJ, I created an artifact "JavaFx application" and configured it as it is written in the instructions for TornadoFX.
project settings
project settings
The executable file builds successfully, but when I try to run it I get the error "No method main in class com/example/demo/app/MyApp."
I tried to add main to the project code, as it is written in the instructions for TornadoFX, but I cannot specify this method in the project settings.
project settings
Only the MyApp class can be added automatically, but of course it does not contain the main method.
project settings
What am I doing wrong and how can I make an executable file under Windows?
My code in MyApp.kt:
package com.example.demo.app
import com.example.demo.view.MainView
import tornadofx.App
import tornadofx.launch
class MyApp: App(MainView::class, Styles::class)
fun main(args: Array<String>) {
launch<MyApp>(args)
}
Once again I carefully re-read the manual for TornadoFx and saw the important phrase: "Notice the Kt at the end.". Thus, in the project settings in the Application class field, you need to add "Kt" by hand. I did it and it worked out as I wish.

Why aren't "internal" types in the main source tree visible in my unit tests?

I've got a Kotlin project in IntelliJ that is structured like this:
main/com/foo/Bar.kt
test/com/foo/BarTest.kt
where Bar is defined as:
internal class Bar
and BarTest is something like:
class BarTest {
private lateinit var bar: Bar
}
I'm getting compiler errors in IntelliJ on the reference to Bar with the message:
Cannot access 'Bar': it is internal in 'com.foo'
The tests, however, compile and run from the command line (via Gradle).
How can I suppress/remove this error when using IntelliJ?
My setup is:
macOS 10.14.1
IntelliJ 2018.2.6
Kotlin 1.3.10
I opened up two projects concurrently using the same IntelliJ installation:
a former project in which I was able to unit test an internal class located in the main source tree (all within the boundaries of the same IntelliJ module)
the current project in which I was unable to reproduce this setup
The fact that IntelliJ still gave no errors in the former setup led me to conclude the issue was not to do with my IntelliJ setup. As #JaysonMinard suggested, I looked at the differences in the Gradle configuration.
The difference was in the current project's top-level settings.gradle, I use the convention of renaming modules, a la:
findProject(':module-blah')?.name = 'blah'
...so as to refer to my Gradle projects by shorter names while having them listed contiguously in my project browser (rather than being scattered around with other files alphabetically). Removing this shortcut restored the behavior I was looking for in my unit tests.

Muting Java 9 split package errors on IntelliJ

I have a JDK 9 project. When running mvn install, everything works fine. When using IntelliJ 2017.2.6 with JDK 9.0.4 I come up
with dozens of compilation errors due to split packages. For example, in my POM I set a dependency on org.apache.solr:solr-core:7.2.1. One of the errors displayed by IntelliJ is:
Error:java: module solr.core reads package org.apache.lucene.search from both lucene.misc and lucene.sandbox
The rationale for the compilation error issued by IntelliJ is:
solr-core has Maven dependencies on artifacts lucene-misc and lucene-sandbox
Both lucene-misc.jar and lucene-sandbox.jar define classes in package org.apache.lucene.search
IntelliJ considers that lucene-misc.jar and lucene-sandbox.jar are JDK 9 modules (if fact, they are not modules, they have no module-info.java file). As two JDK 9 modules cannot participate to the same package, IntelliJ issues a compilation error.
By contrast, the Maven compiler pluging issues no error, because it considers lucene-misc.jar and lucene-sandbox.jar as belonging to
the class path, not to the module path.
I obviously don't want to re-package the Lucene stuff.
So my problem boils down to the following: how can I mute IntelliJ errors Error:java: module Mod1 reads package P from both Mod2 and Mod3?
[Short]
It's impossible if you want to run your application from a module code. You have to migrate your code which depend on collision JARs to non-module code and add your collitions jar on the class path. (as suggested in comments)
[Long]
Behind the scene the Intellij try to run the JVM, so the Intellij can run your application only if the JVM can do that.
When you run an application from module jar, that means that you run your application from named module. The module must require all of its dependencies which should be name modules. Note that even automatic modules which are created from your non-module JARs are indeed named.
Java 9 does not allow split-packages for the reason of the reliable configuration, only unnamed modules are excepted from this rule.
The only way to make it works it move your collision jars to unnamed module, but named module cannot depend on unnamed module
A named module cannot, in fact, even declare a dependence upon the unnamed module. This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make reliable configuration impossible.
so if you don't want repackage collision jars you have to move your modules which require collision jars to non-module jar.
Your maven plugin done with it, because as #Nicolai said:
Maven places them on the class path (where split packages don't matter), whereas IntelliJ places them on the module path (leading to the problems you observe).
See also this answer about running the application from non-module code.

How to make IntelliJ reference source code in another module?

I have a typical project structure:
- root-dir (not a project)
\- core-module (a gradle project)
\- application (a gradle project)
Both core-module and application are imported into IntelliJ and kept on Auto Import. In application's build.gradle, core-module is referenced as:
compile('my-group-id:core-module:0.2.0-SNAPSHOT')
where 0.2.0-SNAPSHOT is the current version as declared in core-module's gradle.properties.
In application, when I try to view a class from core-module, I'm brought to the source code in core-module-0.2.0-SNAPSHOT-sources.jar, instead of the corresponding source code in the core-module module.
I know I can manually add core-module as a module dependency in application, but next time anything in application's build.gradle changes, auto import will overwrite that dependency.
Is there any way to make IntelliJ recognize automatically that I'm trying to view a class from another module and go there instead of the downloaded sources jar?
Furthermore, is there any way to make IntelliJ always prefer the core-module module over the dependency jar, not only for code viewing, but for building/running/debugging/etc.?
All the source files are in Kotlin, FWIW.
Use Gradle's composite build. Gradle has composite builds https://docs.gradle.org/4.4/userguide/composite_builds.html that allow one to 'include' a build directly, rather than from a repository.
IntelliJ also supports this functionality. This was added in 2016.3.
Here's a webcast:https://blog.jetbrains.com/idea/2017/03/webinar-recording-composite-builds-with-gradle/
In the Gradle tab, right-click on your application module. The menu will have a 'composite builds' option. On the dialog that appears, check the 'core-module' module and close.
Now, right-click on application module and do a 'refresh Gradle project'. I've found if I don't do this, the dependency doesn't get updated correctly.
To verify, look at the dependencies under the sourceSets. Instead of a version #, it will now look like a module dependency.
This provides many benefits. One is the navigation you were looking for. In addition, any changes made in core-module are immediately available, and used for the application.
Refactor a method in core-module that is used by application, and IntelliJ will refactor all usages.
Enjoy!

Appcelerator Titanium developing iOS native module - having more than one module inside the package

If I create a new module project than the templates comes with a default named convention class that inherits from TiModule.
I would like my module to encapsulate more than one module inside it, so I've created another class that inherits TiModule with the name or MyNewModuls.m
Everything compiles and built, but how can I call methods I've created on that module from javascript code? When I require my module, only methods from the original module file that inherits TiModule exist.
You cannot add multiple module subclasses in side a module package. Please check the Titanium Module documentation. In that the above scenario is clearly mentioned a module cannot have multiple module classes.