Spring Cloud Contract: Prefered way to import repeating parts in Contract DSL - spring-cloud

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?

Related

Assemble transitive closure of a main file in scala sbt project

I'm working on a scala sbt project, and I am at a point where I want to assemble the whole thing to share a .jar-file with others, so that they can use it on their side. For my local testing, I'm doing so using the sbt-assembly plugin, that works nicely.
When sharing, I would though prefer to only share the parts that are important for the other party (the project has huge components that irrelevant at the current point, and I'd prefer not to share these for various reasons). Concretely, they will be executing one particular main file, so it would be enough to pack everything that this file depends on.
Is there a way to accomplish this? I'd also be interested in doing this on the code level (i.e., create a copy of the project that only contains dependencies of that main file), but also while assembling or even modifying the jar file after assembly is okay. I did not find the tools to achieve any of these.
As I said, I'm dealing with a scala sbt project, and I'm working with IntelliJ IDEA; I'd also be happy with an IDE tool that does the job.

groovy scripts and classloader - content assist in eclipse - what to do?

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.

IJavaProject without Eclipse Environment in JDT

I have an exported Eclipse Java Project in my server and I want to be able to compile the project and use ASTParser with JDT.
I'm able to compile the project using BatchCompiler, however it runs on console and gives me PrintWriters instead of an array of problems and errors. Also I want to be able to use proposals in Eclipse and BatchCompiler didn't built for this purpose.
Therefore I tried to use ASTParser, it can be used with either char[] or ICompilationUnit. CompletionProposalCollector and org.eclipse.jdt.internal.compiler.Compiler.Compiler needs ICompilationUnit so I have to create an ICompilationUnit which only can be created by an IJavaProject (https://dl.dropboxusercontent.com/u/10773282/2012/eclipse_workspace.pdf) in order to be able to use these features.
It seems the only way to create IJavaProject is to use ResourcesPlugin.getWorkspace(), however it returns java.lang.IllegalStateException: Workspace is closed. on my computer and it seems the reason is that the program that I coded is not an Eclipse plug-in.
Is there any way to create IJavaProject without Eclipse environment?
From the comments, it looks like you are trying to do more than just parsing, you actually want to get some form of content assist.
I'm afraid that you're asking for too much. There is no simple way to get the power and flexibility of JDT outside of a running Eclipse instance (believe me, I've tried). There's no simple way, but if you are brave and strong willed, you can one of try following:
Run a headless Eclipse on your server that works on top of an actual workspace. This would be the easiest to implement, but would be the most resource intensive and least flexible way of doing things.
Use the jdt core jar, and create alternate implementations of the IResource hierarchy, and the parts of JFace that are used by the the parser and the CompletionEngine. This would likely be the most feature-rich way to go, but also the most brittle. I can't guarantee that this would work as you may need to create some very complex stubs for internal Eclipse non-API classes.
Avoid the CompletionEngine and the ASTParser entirely and just use the batch compiler. You would then need to provide an alternate implementation of org.eclipse.jdt.internal.compiler.env.INameEnvironment. This implementation would be able to find types, files, and compilation units in your actual project structure. You'd need to reimplement support for content assist, but this would most likely work reasonably well.
I am actually fairly interested in doing something like this (but I lack the time to do it). If you are seriously considering creating a headless JDT that can run on a server, feel free to ask for more information. I am quite familiar with JDT internals.
I've had a similar problem. Here is how to use ASTParser without Eclipse (it just needs the core JDT JAR on the classpath): http://blog.pdark.de/2010/11/05/using-eclipse-to-parse-java-code/

Restricting Java package access

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.

How to share files among several Eclipse projects using SVN?

A bit of context: I am practicing with the former editions of the Google Code Jam, and trying to solve a lot of these puzzles in Java. For each puzzle I create a specific project in Eclipse.
I also built a little "Sample" solver project containing usual operations on input/output files, handling of test cases, script files to run the program on a file quickly, and so on. Now I am using this framework on every puzzle, simply modifying a core "Solver" class which contain the main algorithm. All other files stay the same on every project.
My problem is, I am versioning my work but clearly the only relevant source code to version for each project is this Solver class (and some input/output files). All the rest is duplicated and I would like it to be easily updated when I modify something in the sample project.
On the other hand, I want to be able to easily checkout a project and get it fully working.
I was thinking of using SVN externals to do this but external definitions apply only to subdirectories - and my relevant files are in the same folders as the duplicated ones.
Also SVN ignore does not fulfill my purposes because I would still have to manually replicate any change to my sample project throughout each project.
Do you know of a good way to handle this? Thanks!
Code reuse is typically not accomplished using the version control system, but using polymorphism or libraries. One disadvantage of using the version control system is that you have to do a svn update to pull the new externals from the repository, which strikes me as awkward if you have many projects checked out. Another thing to consider is the development workflow when modifying the reused code. To test your changes, you will probably want to run them with a particular solver, but to do that, you need to svn update - and I am pretty sure you will forget to every once in while, and wonder why your bugfix has no effect ... Therefore I recommend one of the following two approaches:
Polymorphism
Put all your solvers in the same project, making reuse rather trivial. To invoke the right solver, you could do something like:
interface Solver {
// your methods
}
class Ex1Solver implements Solver {
// your solution
}
public static void main(String[] args) throws Exception {
Solver solver = (Solver) Class.forName(args[0]).newInstance();
// work with solver
}
Library
Define an eclipse project for the reused test harness, and a project for each solution. Declare the reused project as dependency of the solution project (In eclipse, right click on the project -> build path -> configure build path -> projects -> add). The test harness would create the solver in the same way as in the polymorphism solution.
You can use svn:externals with files (starting with 1.6) as well, but i would think about a solution on base of a library, cause it's sound like your "framework" is such a kind of thing.