when i build a kotlin project, are resources from ...
# announcements
c
when i build a kotlin project, are resources from main/kotlin and test/kotlin not copied to the classes directory? i want to load json files in my unit tests with
Copy code
javaClass.getResource("myJsonFile.json")
but it does not work.
v
No, they should be in
src/main/resources
or
src/test/resources
.
src/main/kotlin
and
src/test/kotlin
are as their names suggest for Kotlin files, not for resource files.
c
hmm thats really disappointing if you want to keep your test resources next to your test classes, and I think it worked differently at some point
v
You can always configure it however you like. But that's the conventional default in Gradle (as well as in Maven afair).
c
it makes sense, but its not very practical if you want to extract big strings from your kotlin test source and put it near the source file
v
It's a matter of PoV whether it makes sense / is practical to have the resources near the sources or not. That's why Gradle employs best practices as convention but gives you the power of defining it however you want. If you want the resources with the sources together, just configure your project that way. 🙂
e
IDEA might have some issues with overlapping source roots if you mess around with it, but Gradle itself should be fine
n
I actually am surprised that resources is a subdirectory of srx
src
I wouldn't expect src to contain anything but source
v
It is a kind of source. It just is not source*code*. Actually Maven came up with that convention and Gradle adopted it, as it makes sense.
In
src/main/antlr
you by default have the antlr grammar definition file from which sourcecode will be generated that will be compiled alongside your other sources.
n
I think we define source differently. An input file for sourcegen is still source, it's an input to the build. A file opened as part of a unit test isn't, it's something used at runtime. At any rate the convention is overwhelmingly different in the C/C++ world, so I guess different people have reached different conclusions
v
Source even is part of the name resource. :-D Every file that somehow ends up in production (the test runtime environment being production for test source files) can be considered a source of the program, be it source code, a file with localization strings, a logging configuration or an image. Might be, that cpp devs see this differently, but that is the view most Java ecosystem developers share. :-)
👀 1
👍 1
c
java has a Class.getResource method and that method searches the resource in the same package where the class is. and with the src/main/kotlin src/main/resources separation you have to recreate the package structure and its hard to find. so thats just not as useful as it could be.
also idea has this as default resource patterns: “!?.java;!?.form;!?.class;!?.groovy;!?.scala;!?.flex;!?.kt;!?.clj;!?*.aj”. its pretty clear that that comes from a time where there was no separation between src/main/java and src/main/resources.
v
iirc the Android plugin sets it up so that you can mix Kotlin and Java sources in the same folder, for easier incremental switch from Java to Kotlin. As I said, Gradle is very flexible and lets you easily set up any pattern you prefer. Just the conventional defaults are what years of experience of many developers has shown makes the most sense for the most people.
c
either that or nobody actually remembers why src/main/java and src/main/kotlin and src/main/resources even exist. and it just stays that way because thats how it has always been
deep directory hierarchies that work only with ides are a legacy that we have from java. a first step to fix it is people no longer using reverse domain names as package names. but things can always change if there is a better way.
e
there's good reason to keep java and resources separate. I have projects with .java and .kt files that are not meant to be compiled, but instead are data files used to build sources to feed to another compiler at runtime. they live in src/main/resources
c
well sure, that definately should be possible, but it should not influence whats the default
v
deep directory hierarchies that work only with ides
why should they only work with IDEs? It's even better for usage without IDE, as it is clear what resources you have. That it might not work for you does not mean it does not work for others.
a first step to fix it is people no longer using reverse domain names as package names. but things can always change if there is a better way.
So, what is the "better" way to have unique package names? What is wrong with reversed-domain-name? I think that's a great convention, also immediately shows where you might get more information about the code. Just that some people don't like the convention does not make it less helpful.
well sure, that definately should be possible, but it should not influence whats the default
Again, it is Gradle not Maven. You are free to use any layout you want.
c
I’m even free to propose a new standard layout 🙂
and on the working without ide topic: just browse a java project on github and compare that with browsing a scala or javascript or ruby project. the java project is scattered over 100s of almost empty directories
v
Of course you are, I just doubt you will have success with that, as for most people the current default makes sense. But yeah, no change without initiative, so go on.
well sure, that definately should be possible, but it should not influence whats the default
You must be browsing really strange projects.
c
anyway for my use case it works pretty well if i just use the package view and group it by module
👌 1
but even idea has long standing usability bugs related to these duplicated directory hierarchies. for example this from 5 years ago: https://youtrack.jetbrains.com/issue/IDEA-146926
v
Well, that is also a matter of how you work with your tools or what road you follow. I see no need for such a functionality for me for example. Because then it would create two empty directories and one maybe stays empty because I don't write a test. And if I want to write a test for a class in the same package I simply press Ctrl+Shift+T and it creates the directory structure for the package automatically.