Goal:
I want to define groovy classes in .groovy files as part of a package, but without ever needing to compile them. Then, I want to define groovy scripts in the same package, import the class definitions from the nearby .groovy files, and execute the script... all without compilation.
Problem,
This appears to be possible using GroovyClassLoader() (and several people have posted how-tos). However, the problem I have that nobody else seems to reference is that this strategy means that content assist will never be able to identify your classes and methods, and your code will be full of underlines, and receive no error checking.
You might say "Thats just a side effect of using such a dynamic feature, how would eclipse be able to know?", but consider the following:
As I was building my project, I was creating the scripts and the classes in the package just like normal a program. When I add my import statements for my custom classes, Eclipse recognizes everything and content assist is happy. However, despite content assist being satisfied, it hits a snag when I try to execute a script because eclipse returns: unable to resolve class (presumably because it's still only a groovy file, and not compiled to a class file).
So, I looked around and it looks like I have to comment out the import statement, and then use groovyclassloader to parse the groovy file instead. However, this has the negative side effect of breaking content assist.
Question: Are my conclusions above all basically correct?
Suggestion: Is there any known way to have content-assist work along-side with GroovyClassLoader? Maybe some way to tell it to ignore failed imports or something?
It turns out this was a problem with the way I had configured my classpath. Once I had my folder structure consistent with the package structure, eclipse found my class files and was able to import the classes.
Related
When writing a contract for an API i found myself repeating the same things over and over. For example regex validations for complex json object need to be copy pasted.
Thats tedious and not very DRY.
I'm using Kotlin DSL and Maven
I tried to extract the common parts in another file to reuse it. (Kotlin extension functions ftw.)
After trying multiple things to reuse that file I gave up.
The common parts should be as close to the actual contracts as possible. I don't want to export them in another project, and build them seperat, as they are an vital part of the contracts.
I tried it the following ways:
just put the file in the same directory and importing the functions, hoping it would be resolved as it would in java - did not work at all (my expectations were low, was worth a shot)
putting it in another maven module, and add that as dependency to the spring-cloud-contract-maven-plugin. that worked, as long as the dependant module was built and installed in the local maven repo. if no built version was available maven could not resolve it.
experimenting with kotlin script #file:Import() and #file:DependOn to tackle my issue, no luck.
Is there another way, that I missed? Is there a prefered way doing this?
This must be a common issue, right?
I'm in the process of developing a shared library for Jenkins with scripts in vars/ and classes in src/.
I have these two stumbling blocks:
I use a Jenkins-specific method sh or echo. It is greyed out because Eclipse doesn't recognize it as a proper Groovy method. Is there a way to make these "known" to Eclipse?
I create a file vars/foo.groovy with two methods, call() and helper(). Using foo() anywhere int he program results in it being greyed out, suggesting that Eclipse doesn't know what this refers to. Is there a way to make Eclipse understand that foo() is now a legal method?
Note that inside foo.groovy, both call() and helper() are recognized as valid methods. The same holds true for a class src/clazz.groovy - using new clazz() gets recognized everywhere in the shared library as valid code and the shown doc refers to the clazz.groovy file.
All of this works fine if run on Jenkins, this is purely about syntax highlighting and, if possible, showing the Javadoc when hovering over the functions. Syntax highlighting is the main concern, though, as it is a PITA to deploy a shared library only to notice there's a typo in some function somewhere I didn't catch because it's all greyed out.
The default Groovy syntax highlighting works, this is just about methods relating directly to Jenkins and/or the shared library.
This doesn't help me as it refers to IntelliJ which is sadly not an option.
You can add individual inference suggestions using quick assist (Ctrl+1) or you can create a DSLD that gives more complete slash complex information. If your script is using methods defined by a specific type, you can use #BaseScript annotation.
If your scripts (in vars folder) are not part of project classpath, they won't be available for import or static import.
The Jetbrains Kotlin compiler in Eclipse outputs to a hidden folder inside the Eclipse compiler plugin. This hidden folder is then made available through the Eclipse Kotlin classpath container.
In bndtools we need a normal file system folder since bnd can run both from the file system as well as in Eclipse. Since the folder is a linked resource there is no known way to translate it outside Eclipse.
Anybody knows how to tell the Kotlin compiler to just output it in the bin folder?
Currently, this is not possible in the Kotlin Eclipse plugin.
To make it possible that Kotlin code can be used from Java, Kotlin plugin produce so-called lightweight class files to this folder. These class files do not contain bodies for methods and they are stored in memory.
Actual class files, that are used to run an application, are being built only before launch and they are produced to the default output folder. For now, we cannot produce class files on each save reasonably fast as there is no incremental compilation in the plugin yet:
Feel free to upvote for this issue.
From the short analysis of the code of Kotlin plugin, it looks like the proper method is KotlinCompiler.compileKotlinFiles. It is being called in two contexts:
KotlinBuilder.build — this is the one called on the project build; it makes a call stack trick (or rather a hack...) to check if being called from the LaunchConfigurationDelegate, and depending on the results, either compiles whole project (via its own private fun compileKotlinFiles), or just makes stubs in memory.
KotlinCompilerUtils.compileWholeProject — this is in fact being called from 1.; nice static method, perfect for abuse until the problem is correctly solved in the plugin. :)
So, I'd use the method from 2. wrapped in a similar way as compileKotlinFiles from file in 1.
Unlike Java, Scala does not require the location of a file to correspond to the file's package declaration - e.g. a file in the package com.company.project need not be in com/company/project. My company's Scala projects have a directory structure that does not correspond to their package structure, and the Scala compiler is quite happy with this.
However, when moving or copying a Scala file, IntelliJ automatically changes the file's package declaration to match its location. To work around this, I have to either manually revert the change or use a separate tool to do these file operations.
Is there a way to disable this behaviour?
(This question is related but doesn't describe the exact behaviour I'm talking about.)
This is not currently possible. A request for this feature has been opened on JetBrains YouTrack here.
Ie. I have a GUI package, and a Logic package.
How can I prevent the Logic classes from importing GUI classes? Others(or myself) working on the same project might do that, which I want to prevent.
A solution could for example be a check in JUnit, that fails if its done, or a runtime check that throws an exception. Something along these lines, but how to do it?
You can write such a test using JDepend or DependencyFinder or Degraph.
Degraph is the only of the three tools that explicitly is intended to actually write tests for cases like this. Also AFAIK JDepend does not find all dependencies in more recent Java Versions (like classes mentioned in Annotations).
I'm the author of Degraph so I'm obivously biased.
I created the JabSaw project. It allows you to define modules by using annotated classes and to express the relationships between the modules. By default, a module contains all classes in a single package.The restrictions can be checked using a Maven plugin, from the command line or from a unit test. This should solve your problem.
One solution which comes to my mind is make GUI classes package private. Although you cannot isolate only one package and say, only Logic classes cannot use GUI, but other can.