I’m using the immutables.org and mapstruct annotation processors in my sbt project (I've moved them to subprojects, so they don't interfere with each other).
Sometimes, compiling my project fails in compileIncremental because the annotation processor would create a new file, but the compiler already read the previously generated file or I changed my interface in src/main/java but the (previously) generated sources still "implement" the old interface (they would be overwritten, but that happens only after processing the sources in src/main/java).
My workaround was to create a task that deletes the generated sources beforehand for which "(compile in Compile)" would depend on.
Is there another way to do this? like disabling compileIncremental for one single project? or specifying the order of compilation? (like first normal sources, then unmanagedSources)
Alternatively finding out if the sourceFiles really changed and only then deleting the generated sources would also work for me, but I’m not sure how to approach that.
Any help would be greatly appreciated!
Thanks,
Dominik
Related
I have successfully configured Proguard with Maven to obfuscate a jar, and its dependant jar. I have managed to get both obfuscations to use the same mapping file, so that one jar can call the methods of the other. The problem I am facing, is that Proguard is not keeping unique names across the obfuscated jars; both obfuscated jars contain a class called
f.b.class
As there are two classes called f.b.class (one in each jar), priority is being given to the class inside the calling jar, which is causing problems.
Has anybody experienced this before and are you aware of a solution for this. Currently I am using the
-keeppackagenames
switch to ensure that the package hierarchy remain different so that any duplicated class names do not conflict. Ideally I would like to remove all package names
The switch
-useuniqueclassmembernames
has also been applied but it clearly only applies this to the jar currently being obfuscated. It does don't look and previously obfuscated jars to ensure uniqueness across jars.
Thanks
To resolve this I ended up using the -keeppackagenames option. It is not a solution, but a work around.
Our project has started newly and wanted to know some of the best practices followed in industry. We have generated lot of DTOs(getters and setters) code for webservices using JaxB. we keep all the DTO classes along with regular pojos(logic written), its looks like large project due to this auto-generated code, also for code coverage it considers these classes also.
I am keen to know that these classes should be as a jar file in classpath or it should be as classes in project.
Thanks in Advance,
Madhavi
If your project uses Maven (or something similar) I would advise having the code generation and the generated code in a separate module of a multi module project.
This way the generated stuff is out of the way of the hand crafted code. You can also set up your Maven build process to then build this module first and the rest of the code can rely on the resulting artefact, be it a jar or something else.
You could also regenerate the generated code on each new build this way. Although this can be a lengthy process, depending on the service.
Generated files should not be mixed with your written files.
A common approach is to generate them to the target folder, e.g. target/generated-sources or something similiar. Of course, if they are rarely changed, you could also put them in a jar file that you import into your project.
I think its better to keep them in jar. As its auto generated code and no one is supposed to change. Whenever regenerated include new jar.
Suppose I have have a java project myProject and am using an external library jar (someJar.jar), which has a class com.somepackage.Class1.class.
Now I find an updated version of Class1.java which fixes a bug in the original jar.
I include the new Class1.java in my source code under package com.somepackage
When I build the project (e.g., using Netbeans), there is a dist\myProject.jar which contains the classcom.somepackage.Class1.class and a dist\lib\someJar.jar which also contains a class with the same name.
When I run the file (e.g, using java -jar dist\myProject.jar), the new version of Class1.class is used (as I want).
How does Java decide which class file to run in case of such duplicates? Is there any way I can specify precedence ?
Is there any 'right' way to avoid such clashes?
In Proguard, when I try to compress my code, I get a duplicate class error. How do I eliminate this?
Java decides which one to use based on the order of the classpath. List yours first and you'll be fine.
The "right" way would be to fix the orignal source, but sometimes that's not always an option.
I haven't used ProGuard, but I have re-jarred libaries before that had duplicate classes. The solution in my case was to tell Ant to ignore duplicate classes. I would assume ProGuard would have that support too.
Can you not create an updated jar file which contains the bug fix? It's going to make things a lot simpler if you don't have two versions of the same fully-qualified class around.
1) Updated Jar is a better solution.
2) Use a different class name. Is there a reason, why you want to use the same class name and same packing? I don't think there is a reason.
3) create a wrapper/ proxy class, that encapsulate all the calls to the jar and you can decide to call this new class that fixes the bug ( provided it has a different name and packaging)
I am using a 3rd party annotation processor for generating meta-data code (.java files) from the annotated classes in my project.
I have successfully configured the processor through Eclipse (Properties -> Java Compiler -> Annotation Processing) and the code generation works fine (code is automatically created and generated). Also, Eclipse successfully auto-completes the generated classes and their fields, without any errors. Let's say that I have a class "some.package.Foo" and that the generated meta-data class is "some.package.Foo_". By the help of auto-completion, I can get the following code in the Eclipse editor, without any errors:
import some.package.Foo_;
...
public class Test {
void test() {
Foo_.someField = null; // try to access a field from the generated class Foo_
}
}
However, as soon as I actually build the project (or just save the file since Build automatically is enabled), I get the error which tells that "some.package.Foo_" cannot be resolved.
It seems like Eclipse is generating and compiling the some.package.Foo_ at the same time, or more likely.
I found two temporary solutions (which are practically hindering the use of the annotation processor in the first place):
Before each build of that generated classes, right click on every generated file go to Properties and uncheck the "Derived" tick. After that, I do the cleanup of the project and the imports are fine - there are no more errors. However, if I do the cleanup one more time, the errors again show up, because the generation of the files causes the "Derived" tick to be checked again (automatically). So this is really annoying and time-consuming.
I also uncheck the "Derived" tick
from all those files, and this time
I uncheck the "Derived" tick from
the source folder and packages which
contain those files. Then I disable
the annotation processor, and then
do the cleanup. There are no more
import errors, even if I do another
cleanup, but there is no benefit of
using the annotation processor,
because if I was to change something
which would update the model, I need
to turn the annotation processor
back on, and repeat this tedious
procedure to turn it off, after it
has generated the new version of
those files.
Is this a bug in Eclipse? If yes, is there a better workaround or quick-fix than the two I have stated above? If not, what should I try to solve the problem?
I also tried rearranging the order of the libraries on the build path and it doesn't help.
I assume that you are generating sources in the last processor round. This is not recommended way and leads exactly to the problem that you had.
Explanation is here: http://code.google.com/p/acris/wiki/CodeGenerationPlatform_Pitfall_Rounds
So the my advise is to generate sources in regular processing rounds and final round should be used just for notification that processing is over or something like that.
Hopefully this helps you.
I have a similar problem, and the only thing I've found is that it's the imports specifically that don't work, but the references in the class itself do work. The workaround I've used is to use the FQCN in all cases where the generated class is needed (except when the generated class is in the same package, since then the import is obviously not needed).
So to use your example, I'd do:
public class Test {
void test() {
some.package.Foo_.someField = null; // try to access a field from the generated class Foo_
}
}
My only guess then is that the eclipse compiler is processing the imports before doing the annotation processing, which imho must be a bug in eclipse.
I know this question is over a year old, so I'd be interested to know if you've found any other way to fix it.
We were experiencing a similar problem and apparently just solved it, so thought of sharing it at SO, in case it helps someone.
We are using:
Eclipse Indigo (Build id: 20120216-1857)
m2e Connector for maven
openJPA for static metamodel class generation
Our problem:
Say, we have a package named com.abc.xyz and an entity class in there named OurEntity. When we build the projects (JPA, EJB, EAR etc. all together with an mvn clean at the beginning) the metamodel classes get generated. And also get appropriately packaged within the PU jar. But when we try to import the generated metamodel class com.abc.xyz.OurEntity_, Eclipse cannot resolve it. OP apparently got past this point:-). Maven build failed, saying it could not resolve that class. Not much help from google except for a few bug reports such as this one: https://bugs.eclipse.org/bugs/show_bug.cgi?id=350378
That bug report said importing the whole package as opposed to the single class helped. So, tried that, but with no benefit. It also said (and so did David Heitzman) that using the fully qualified class name worked for them. That did not work either.
The solution:
Added the PU jar to Eclipse build path for the project that needed to use the metamodel classes. All of a sudden all the red underlines went away (not a surprise). But the fear was there might be two PUs in the same ear. But maven automagically took care of that.
As this rather old question got some attention without pointing to the very probable eclipse bug the OP was specifically asking for, I'd like to complement the above answers with a pointer to the eclipse bug tracker:
Cannot resolve import for generated class IF processing annotations with parameters referencing constants
The workarounds include
doing a wildcard import of the package defining the generated classes (i.e. import some.package.*;)
using the fully qualified name of your generated class, i.e. referring to some.package.Foo in your code and not using an import
switch to a newer Eclipse. This specific eclipse bug is resolved with Eclipse version 4.4 (aka Luna).
I'm doing a build script for a Java application to run inside the Oracle JVM. In order to import the 50-odd classes, it appears I need to bring them in in order, so any dependencies are present before compilation.
For each class, I'm running 'create or replace and compile java source {className} as {classPath}' for each file. Doing this gives me a compilation error, as the required class(es) are not imported.
How can I generate a list of the classes, in dependency order - that is, as you go down the list, the class's dependencies are listed above. I would prefer to do this as an Ant task.
Also if you have a better idea of how to get these classes imported, I'd love to hear your ideas.
I can't imagine why you'd need to do this, but if you really need to do this, I wonder if hacking a little classloader that prints out each class as it loads and load your app from there would give you a dependency graph?
Compile the classes in the filesystem using the Ant task javac. Use the task depend if more rigorous dependency checking is needed. Use the loadjava tool to load the .class and .java files into the database in arbitrary order.
In order to import the 50-odd classes, it appears I need to bring them in in order so any dependencies are present before compilation.
I have never had to do such a thing simply to compile Java.
This is what Ant was born for. I'd recommend just doing this with Ant. Set the <classpath> and you'll have no trouble.
Brute force method: put the 50 CREATEs in a batch file and execute it until no errors are found. Create the loop in a shell script. Of course it will never end if there are errors in the sources, but I'm assuming they are ok.
Can you not load in a jar file? Why does it have to be individual classes?