I have observed that the domain class compile output file(.class file) keep changing without modification to the source file(.groovy) in grails.
see:https://github.com/grails/grails-core/issues/10868 .
And grails domain class compiled output file keep changing without modification .
I doubt it's something related to groovy AST injecting.
I have tested normal groovy class(without any AST), the compiled byte code is identical every time. Anyone can explain this symptom?
Related
I'd like to take advantage of #CompileStatic annotation in my groovy scripts in jmeter environment. It helps a lot to discover issues in compile time.
I already started to use it in my classes but I don't know how to use it in case of plain groovy scripts. For example, I have the script below and there are the log and vars variables which are kind of global variables in JMeter environment. So, eventually they will be used.
If I add the #CompileStatic annotation to the method below IntelliJ paints red everything and compile will fail because the compiler doesn't know what these variables are.
So, the question is how to tell the compiler in a case of a script these variables has type and what type they have, and how an instance will be provided for the script?
I apologize, I'm not a groovy expert at all.
void checkingInputParameters() {
log.info("variable value:" + vars.get("some_variable_name"))
}
checkingInputParameters()
I think you are in the wrong path,
because CompileStatic is a groovy compiler option
let the Groovy compiler use compile time checks in the style of Java then perform static compilation, thus bypassing the Groovy meta object protocol.
JMeter (and I assume your tests in Intellij ) is using a java compiler
I don't think you should mix them for tests.
In JMeter use Cache compiled checkbox/feature
checking Cache compiled script if available
I am trying to write source code in one language and have it converted to both native c++ and JS source. Ideally the converted source should be human readable and resemble the original source as best it can. I was hoping haxe could solve this problem for me. So I code in haxescript and have it convert it to its corresponding C++ and JS source. However the examples I'm finding of haxe seems to create the final application for you. So with C++ it will use msbuild (or whatever compiler it finds) and creates the final exe for you from generated C++ code. Does haxe also create the c++ and JS source code for you to view or is it all done internally to haxe and not accessible? If it is accessible then is it possible to remove the building side of haxe so it simply creates the source code and stops?
Thanks
When you generate CPP all the intermediate files are generated and kept wherever you decide to generate your output (the path given using -cpp pathToOutput). The fact that you get an executable is probably because you are using the -main switch. That implies an entry point to your application but that is not really required and you can just pass to the command line a bunch of types that you want to have built in your output.
For JS it is very similar, a single JS file is generated and it only has an entry point if you used -main.
Regarding the other topic, does your Haxe code resembles the generated code the answer is yes, but ... some of the types (like Enum and Abstract) only exist in Haxe so they will generate code that functionally works but it might look quite different. Also Haxe has an always-on optimizer/analyzer that might mungle your code in unexpected ways (the analyzer can be disabled). I still find that it is not that difficult to figure out the Haxe source from the generated code. JS has support for source mapping which is really useful for debugging. So in the end, Haxe doesn't do anything to obfuscate your generated code but also doesn't do much to try to preserve it too strictly.
I've been tasked with creating conformance tests of user input, the task if fairly tricky and we need very high levels of reliability. The server runs on PHP, the client runs on JS, and I thought Haxe might reduce duplicative work.
However, I'm having trouble with deadcode removal. Since I am just creating helper functions (utilObject.isMeaningOfLife(42)) I don't have a main program that calls each one. I tried adding #:keep: to a utility class, but it was cut out anyway.
I tried to specify that utility class through the -main switch, but I had to add a dummy main() method and this doesn't scale beyond that single class.
You can force the inclusion of all the files defined in a given package and its sub packages to be included in the build using a compiler argument.
haxe --macro include('my.package') ..etc
This is a shortcut to the macro.Compiler.include function.
As you can see the signature of this function allows you to do it recursive and also exclude packages.
static include (pack:String, rec:Bool = true, ?ignore:Array<String>, ?classPaths:Array<String>):Void
I think you don't have to use #:keep in that case for each library class.
I'm not sure if this is what you are looking for, I hope it helps.
Otherwise this could be helpful checks:
Is it bad that the code is cut away if you don't use it?
It could also be the case some code is inlined in the final output?
Compile your code using the compiler flag -dce std as mentioned in comments.
If you use the static analyzer, don't use it.
Add #:keep and reference the class+function somewhere.
Otherwise provide minimal setup if you can reproduce.
I know that since Groovy 2.0 there are annotations for static compilation.
However it's ease to omit such annotation by accident and still run into troubles.
Is there any way to achieve the opposite compiler behaviour, like compile static all project files by default and compile dynamic only files chosen by purpose with some kind #CompileDynamic annotation for example?
I have found some (I believe recently introduced) feature which allows doing so with Gradle.
In build.gradle file for the project containing groovy sources we need to add following lines:
compileGroovy {
configure(groovyOptions) {
configurationScript = file("$rootDir/config/groovy/compiler-config.groovy")
}
}
or compileTestGroovy { ... for applying the same to test sources. Keep in mind that neither static compilation nor type checking works well with Spock Framework though. Spock by its nature utilizes dynamic 'groovyness' a lot.
Then on a root of the project create folder config/groovy/ and a file named compiler-config.groovy within. The content of the file is as follows:
import groovy.transform.CompileStatic
withConfig(configuration) {
ast(CompileStatic)
}
Obviously path and name of the configurationScript may vary and it's up to you. It shouldn't rather go to the same src/main/groovy though as it would be mixing totally separate concerns.
The same may be done with groovy.transform.TypeChecked or any other annotation, of course.
To reverse applied behaviour on certain classes or methods then #CompileDynamic annotation or #TypeChecked(TypeCheckingMode.SKIP) respectively may be used.
I'm not sure how to achieve the same when no Gradle is in use as build tool. I may update this answer in the future with such info though.
Not at this time, but there is an open Jira issue here you can follow to watch progress for this feature
There was also a discussion about methods for doing this on the Groovy developers list
I am attempting to install my own GroovyResourceLoader and was wondering if there was an authorative guide somewhere describing all hte moving bits.
Ive noticed when groovy attempts to compile a script, it does attempt to find types by sending paths to the GRL. However it does some strange things sometimes it uses '$' as a separator and other times it uses plain old '.'.
Heres a snapshot of some logging of an attempt to load something. Ignoring the auto import stuff, notice how it using '$' as the package separator and then by replacing each '$' it one at a time with a '.'.
-->a$b$groovy$X$Something
-->a.b$groovy$X$Something
-->a.b.groovy$X$Something
Im using Groovy 1.8.0.
The "$" you see come from Groovy trying to match inner classes. I strongly assume you have somewhere an "a.b.groovy.X.Something" which will lead groovy to try to discover all kinds of inner class combinations for this one. You could for example have a "a$b$groovy$X$Something.groovy" file.