Question about fun main() and packages


#1

Hi Everyone ~

My first post here. I’m new to kotlin but fell deep in love with it :slight_smile:

I’m currently learning kotlin by writing some simple programs.

I’m also learning how to use netty by the time, so it came naturally that I’m rewriting netty examples with Kotlin! And it’s FUN :slight_smile:

But here is my first question:

It seems that in kotlin, unlike java, there can be only one main function in a package.

When writing netty server/client example code, I actually need to start those server/clients to play with, each in a different process of cause. So I need a main function for each of those classes.

for example, two classes in the same package, same .kt file

apps.netty.time.TimeServerHandler
apps.netty.time.TimeClientHandler

I can’t write two main functions in this package.


Three solutions I tried:

  1. Try to put those classes indifferent packages

apps.netty.time.server.TimeServerHandler
apps.netty.time.client.TimeClientHandler

But this means I’ll have create a new package for EVERY class, which miss the point of package’s organization

  1. Try put those main functions in Test code.

But it turned out jUnit test won’t let you run a server, it just exits

  1. Create an apps package where I put all my main functions in it, each with a sub package

apps.netty.time.server
apps.netty.time.client

This doesn’t hurt the package organization, but it’s still kind of messy, because I’ll have to put them in different .kt files, because you can’t have more than one packages in a file

The 3rd solution is what i’m currently using

Is there a better way ? Thanks


#2

The 3rd options seems best. You also have 4th option: you can create single main function and use command line option to launch server otherwise launch client as it does some UNIX tools like netcat. For example if you run application with -l option then it will start in server mode. If there is no this option - client.


#3

Reminds me of the good old Smalltalk days where there wasn't any main function at all. Message passing between objects requires no main function. There is only a hook where to place the initial startup message of your application at runtime. That's it. I think Kotlin does it the right way to consider using a main function an exception for practical needs only.


#4

I think, the third option is fine. Also, you can teach JUnit wait for your server to terminate.


#5

Thanks, and for the 4th option, I just found that in IntelliJ I could use Run->Edit configuration to attach some special arguments to a Run Configuration. In this way I could have multiple Run Configuration for one main file. This solution seems fairly well, if I have a good command option parse library.

Now I’ll use solution 3 and 4 combined, where it sees fit :slight_smile:


#6

Thanks :)

I’m wondering how can I tell JUnit to wait for my server?

And if it does, how is that gonna affect auto testing ?


#7

I don't have a particular solution (I think, it can be found on the Internet). The problem is likey to be that the server is started in another thread, so JUnit doesn't know it has to wait. Some kind of explicit notification waiting should help in this case.


#8

Thanks Andrey :)

Then it seems too much work to use JUnit as a main alternative in this case


#9

Then it seems too much work to use JUnit as a main alternative in this case

Have you tried TestNG?


#10

Not yet. I didn't know what it offers other than jUnit. But I'll take a look at it :)  Thanks


#11

TestNG has always been (since before JUnit4 came out) what JUnit4 would like to, and should, become. We should all drop slavish use of JUnit4 and switch to using something better. TestNG. Or Spock.

http://www.testng.org

http://www.spockframework.org