Error with Groovy AST transformations when cleaning project in Eclipse - eclipse

I'm trying to work through groovy's Implementing Local AST Transformations tutorial, but whenever I clean my project I get this error in each file that has the #WithLogging annotation in it:
Groovy:Could not find class for Transformation Processor AC.LoggingASTTransformation declared by AC.WithLogging

So you have a package named "AC" that contains both "WithLogging.groovy" and "LoggingASTTransformation.groovy" classes? Does it also contain any classes that implement the "WithLogging" interface?
If so, I'd suggest you move the class(es) that use your annotation to a location outside of the annotation defining package (the default will suffice, for diagnostic purposes) - Order of compilation matters with transformations. See this post on the groovy users mailing list for more on that.
Also try changing the annotation from #WithLogging to #AC.WithLogging.
As far as cleaning with Eclipse is concerned, I had a similar issue and found that I had to make a trivial modification after a clean to any file that contained my annotation. IE, add a space somewhere. Then save the file. This should rebuild everything properly.

Related

How to create a custom annotation processor for Eclipse

I'm trying to create a custom annotation processor that generates code at compilation time (as hibernate-jpamodelgen does). I've looked in the web, and I find custom annotation processors that works with maven, but do nothing when added to the Annotation Processing > Factory Path option. How could I create a processor compatible in this way? I have not found a tutorial that works.
My idea is to, for example, annotate an entity to generate automatically a base DTO, a base mapper, etc that can be extended to use in the final code.
Thank you all
OK, Already found out the problem. The tutorial I hda found out dint't specified that, in order to the compiler to be able to apply the annotation processor, there must be a META-INF/services/javax.annotation.processing.Processor file that contains the qualified class name of the processor (or processors).
I created the file pointing to my processor class, generated the jar and added it to Annotation Processing > Factory Path and all worked correctly.
Just be careful to keep the order of the processors correctly (for example, hibernate model generator claims the classes, so no more generation will be made after it), and change the jar file name each time you want to replace the library (it seems eclipse keeps a cache). These two things have given me a good headache.
Thanks all

Strange behaviour when importing types in Scala 2.10

Today I cleared my .ivy cache and cleaned my project output targets. Since then I have been getting really strange behaviour when running tests with SBT or editing in the Scala IDE.
Given the following:
package com.abc.rest
import com.abc.utility.IdTLabel
I will get the following error:
object utility is not a member of package com.abc.rest.com.abc
Notice that com.abc is repeated twice, so it appears that the compiler uses the context of the current package when doing the import (maybe it's supposed to do this, but I never noticed it before).
Also, if I try to access classes in package com.abc from anywhere inside com.abc.rest (even using the full path) the compiler will complain that the type can not be found.
It appears that the errors only occur when I try to include files from parent packages. What I do find strange is that my code used to work. It only started happening after I cleaned up my project and my ivy cache, so maybe a later version of the compiler is more strict than the previous one.
I would love some ideas on what I can be doing wrong, or how I can go about troubleshooting this.
Update:
By first importing the parent classes and then defining the current package, the problem goes away:
import com.abc.utility.IdTLabel
import com.abs._
package com.abc.rest {
// Define classes belonging to com.abc.rest here
}
So this works, but I would still love to know why on earth the other way around worked, and then stopped working, and how on earth I can fix it. I had a good look, and could find no packages, objects or traits by the name of com anywhere inside the parent package.
Update relating to Worksheets:
Scala worksheets belonging to the same package share the same scope, which sounds obvious, but wasn't. Worksheets are not sand-boxed - they can see the project, and the project can see them. So all the 'test' object, traits, and classes you create inside the worksheet files, also becomes visible in the rest of the project.
I have so many worksheets that I did not even try to see where the problem came in. I simply moved them all to their own package, and like magic, the problem went away.
So, lesson learned for the day: If you create stuff inside worksheets, it's visible from outside the worksheet.
Anyway, this new found knowledge will come in handy, meaning anything 'interesting' can be build, monitored and tweaked inside the worksheet, while the rest of the project can actually use it. Quite cool actually.
It's still interesting to think how a sbt clean and cleaned up ivy cache managed to highlight the problem that was hidden before, but hey, that's another story....
(At the request of JacobusR, I'm making a proper answer out of my earlier comments).
This can happen if you have defined some class/trait/object inside package com.abc.rest.com. As soon as package com.abc.rest.com exists, and given that you are in package com.abc.rest, com would designate com.abc.rest.com as opposed to _root_.com. Fastest (but non-conclusive) way to check, without even scanning the source files, is to look for any .class files in the "com/abc/rest/com" sub-folder.
In particular you would get this behaviour if any of your files has duplicate package definitions (as in package com.abc.rest; package com.abc.rest; ...). If you have this duplicate package clause somewhere in the same file where you get the error, you wouldn't even see anything fishy with the .class files, as the failure at compiling the file would prevent the generation of .class files for any class definition inside the file.
The final bit of useful information is that as you found out the scala Worksheets are not sandboxed, and what you define in the worksheets affects your project's code (rather than only having the project's code affecting the worksheet). So a duplicate package clause in a worksheet could very well cause the error you got.
If package names conflict, there might be a custom error message for that. See if specifying the full path resolves the issue by starting from __root__. Ex. import __root__.com.foo.bar._

Problems compiling routes after migrating to Play 2.1

After migrating to Play-2.1 I stuck into problem that routes compiler stopped working for my routes file. It's been completely fine with Play-2.0.4, but now I'm getting the build error and can't find any workaround for it.
In my project I'm using cake pattern, so controller actions are visible not through <package>.<controller class>.<action>, but through <package>.<component registry>.<controller instance>.<action>. New Play routes compiler is using all action path components except for the last two to form package name that will be used in managed sources (as far as I can get code in https://github.com/playframework/Play20/blob/2.1.0/framework/src/routes-compiler/src/main/scala/play/router/RoutesCompiler.scala). In my case it leads to situation when <package>.<component registry> is chosen as package name, which results in error during build:
[error] server/target/scala-2.10/src_managed/main/com/grumpycats/mmmtg/componentsRegistry/routes.java:5: componentsRegistry is already defined as object componentsRegistry
[error] package com.grumpycats.mmmtg.componentsRegistry;
I made the sample project to demonstrate this problem: https://github.com/rmihael/play-2.1-routes-problem
Is it possible to workaround this problem somehow without dropping cake pattern for controllers? It's the pity that I can't proceed with Play 2.1 due to this problem.
Because of reputation I can not create a comment.
The convention is that classes and objects start with upper case. This convention is applied to pattern matching as well. Looking at a string there seems to be no difference between a package object and normal object (appart from the case). I am not sure how Play 2.1 handles things, that's why this is not an answer but a comment.
You could try the new # syntax in the router. That allows you to create an instance from the Global class. You would still specify <package>.<controller class>.<action>, but in the Global you get it from somewhere else (for example a component registry).
You can find a bit of extra information here under the 'Managed Controller classes instantiation': http://www.playframework.com/documentation/2.1.0/Highlights
This demo project shows it's usage: https://github.com/guillaumebort/play20-spring-demo

Can gwt analyze dependency like maven does?

How can I get GWT to provide the same dependency insights as mvn dependency:analyze?
Maven can report about dependencies (Used undeclared dependencies and Unused declared dependencies). I'd like to get GWT to do the same because determining missing inherits in my gwt.xml proves difficult.
Is there a good way for the system to analyze dependency state?
Thanks
Peter
I'm not aware of any such tool, and while I think a utility to analyze and report on GWT dependencies could be interesting, I also think it would be difficult to define well.
Used, undeclared dependencies
Before trying to solve this, what is the problem? In maven, this category means that a Class is loaded from a dependency that isn't directly depended on, but instead is transitively loaded. This starts to get into the whole issue of transitive dependencies (which exist in GWT) and scopes (which don't). If A uses a class in C, but only depends on B, which depends on C, this will be listed in the 'used, undeclared dependencies' list.
In GWT however, we very rarely list every single dependency we use directly. Instead, we assume that transitive dependencies will stay transitive - we dont bother to inherit com.google.gwt.user.RemoteService for RPC as long as we already have com.google.gwt.user.User listed.
So how could we tell if we are using an undeclared dependency, the kind that warns when we do a gwt:compile? Perhaps such a tool could find every .gwt.xml file on the classpath, and read through its <source> and <super-source> rules to look for somewhere that a class we are using is declared? Or in the case of invoking GWT.create on something and getting back a non-concrete type, it could look for <replace-with> and <generate-with> rules. As long as your code already compiles in Java, the classes are on the classpath, but you still run the risk that while the class is there, the .java or .gwt.xml files might not be.
Unused, declared dependencies
This seems like an easier problem - analyze the modules we are inheriting, and look through them for any module that could be pruned out. Unfortunately, as the above discussion notes, we can't just look for the classes and which package they are in, which <source> and <super-source> elements are unused - we also would need to look for <replace-with> and <generate-with> rules - consider something like com.google.gwt.user.RemoteService, which only adds a rule and some configuration details, or even com.google.gwt.user.RemoteServiceObfuscateTypeNames, which modifies only a single setting of the RemoteService module. If RemoteServiceObfuscateTypeNames were removed, everything would still compile, but now there might be information about your RPC classes compiled into your app that you don't expect to be there.
With these in mind, perhaps such a tool could watch all possible rebind rules in the current build, and all configuration settings, properties, etc, and see if any of those rules were not using during a gwt:compile process. Then, indicate which modules had unused parts, and if any module (and all of its inherited modules) were unused, it could shown to the user as able to be removed.
One more important piece: order matters, when defining <inherits> statements. If I add a inherits for com.google.gwt.logging.Logging, then follow it with com.google.gwt.logging.LoggingDisabled, logging classes will be on the source path and will compile, but will have no effect. But if those are ordered the other way around, then they will not only be on the source path, but will all be functional. So any analysis of modules used and unused would need to also include transitive inherits statements, and their orders.

Buildr: adding a path to the generated eclipse/idea files

I have a legacy java project that we have been moving to buildr/artifactory from ant/jars in svn.
The primary code is in the default (src/main/java) folder, but we have a few external source paths, for various tests that we can't move into the default folder, but we want to have access with it.
Currently, when adding a new library/regenerating IDE fields, it does not pick up these source paths, and I can't find a succinct discussion in the buildr manual for how to actually add them, rather than re-adding everything manually in eclipse (which just gets wiped out on the next regen).
Any idea how to have multiple source paths get picked up explicitly by buildr so that the idea/eclipse targets generate properly?
There are two ways that I know will work with IDEA. The second one might also work with Eclipse, while the first is specific to the idea task.
The IDEA-specific solution:
define 'proj' do
# ...
iml.main_source_directories << _('src/other')
end
iml also has test_source_directories and excluded_directories arrays you can append to.
The possibly eclipse-compatible solution, with more background than you probably want:
The iml object gets its default values for the main and test source directory arrays from project.compile.sources and project.test.compile.sources (slight simplification; resources are considered also). Buildr defines these .sources project attributes from the layout, so instead of explicitly appending to the iml attributes, you could use a custom layout for your project that includes your special source paths. That might work with the eclipse task, but I haven't tried it.