domaframework / doma

DAO oriented database mapping framework for Java
https://doma.readthedocs.io/
Apache License 2.0
447 stars 70 forks source link

Eclipse M2E APT processing error while trying to find SQL resources #319

Open agentgt opened 5 years ago

agentgt commented 5 years ago

For some reason the Eclipse compiler has issues with finding /META-INF sql files.

The error:

[DOMA4019] The file "META-INF/--/some.sql" is not found in the classpath. The absolute path is "--/target/classes/META-INF/--/some.sql".

(I redacted the real path with --).

It reports an IDE error (red X) on DAO methods that it can't find the SQL files even though when a regular compile is done with Maven it finds the sources just fine (ie mvn package). And yes the annotation processing does run during a regular maven build.

The file does exist on the absolute path (ie target/classes directory) but Eclipses FileObject implementation seems to disagree which I assume is different than the normal javac one.

Thus I experimented by temporarily putting the SQL resources in Maven APT generated target/generated-sources/annotations folder as it has a special attribute of m2e-apt marked in Eclipses' .classpath

        <classpathentry kind="src" path="target/generated-sources/annotations">
                <attributes>
                        <attribute name="ignore_optional_problems" value="true"/>
                        <attribute name="optional" value="true"/>
                        <attribute name="maven.pomderived" value="true"/>
                        <attribute name="m2e-apt" value="true"/>
                </attributes>
        </classpathentry>

I think or believe the m2e apt plugin/bridge needs resources in those directories if they are going to be used by APT tooling (ie hints or warnings in the IDE).

However after I put the resources in those directories I now get this exception which I believe is a bug regardless:

[DOMA4016] An unexpected error has occurred. It may be a bug in the Doma framework. Report the following stacktrace: java.lang.ClassCastException: org.eclipse.jdt.internal.compiler.apt.model.NoTypeImpl cannot be cast to org.eclipse.jdt.internal.compiler.apt.model.TypeMirrorImpl
    at org.eclipse.jdt.internal.compiler.apt.model.TypesImpl.directSupertypes(TypesImpl.java:175)
    at org.seasar.doma.internal.apt.MoreTypes.directSupertypes(MoreTypes.java:69)
    at org.seasar.doma.internal.apt.cttype.CtTypes.getSuperDeclaredType(CtTypes.java:533)
    at org.seasar.doma.internal.apt.cttype.CtTypes.newIterableCtType(CtTypes.java:345)
    at org.seasar.doma.internal.apt.cttype.CtTypes.lambda$newCtTypeInternal$1(CtTypes.java:521)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Spliterators$ArraySpliterator.tryAdvance(Spliterators.java:958)
agentgt commented 5 years ago

I will test on a newer version of Eclipse. I think this is an Eclipse bug based on the commit history of:

https://github.com/eclipse/eclipse.jdt.core/blob/master/org.eclipse.jdt.apt.pluggable.core/src/org/eclipse/jdt/internal/apt/pluggable/core/filer/IdeFilerImpl.java

nakamura-to commented 5 years ago

Doma annotation processors expect that the SQL files and java classes are placed in the same classpath. Are the SQL files copied to the output folder? If you see the inclusion pattern **/*.javaas following, remove it: https://cdn-ak.f.st-hatena.com/images/fotolife/t/taedium/20130820/20130820231548_original.png

By the way, I think that the following bug causes the exception: https://bugs.eclipse.org/bugs/show_bug.cgi?id=531717

Try Eclipse 4.8 or above.

agentgt commented 5 years ago

The SQL files are copied to the output folder but they are located in: src/main/resources as per Maven conventions. Like I said everything works fine when I use maven to do the build.

I upgraded to the latest Eclipse 4.12 and it still happens.

The issue is that the Eclipse APT compiler only looks in target/generated-sources/annotations and src/main/java. It does not look at src/main/resources despite it being on the classpath.

So I could copy the META-INF SQL stuff into src/main/java but that breaks a normal maven build as it expects resources to be in src/main/resources.

Anyway this hack apparently works:

      <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-resources</id>
            <phase>validate</phase>
            <goals>
              <goal>copy-resources</goal>
            </goals>
            <configuration>
              <outputDirectory>${basedir}/target/generated-sources/annotations</outputDirectory>
              <resources>
                <resource>
                  <directory>${basedir}/src/main/resources</directory>
                  <filtering>true</filtering>
                  <includes>
                    <include>META-INF/**/*.sql</include>
                  </includes>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>

The above will copy the src/main/resources SQL resources into the target/generated-sources/annotations. The Maven Eclipse plugin (m2e) will luckily execute the above prior to compiling and the plugin is natively understood by m2e so Eclipse finds the resources.

Anyway a possible code solution is to detect Eclipse and just natively access the file instead of the FileObject.

agentgt commented 5 years ago

I tried doma-tools Eclipse plugin to see if that would help mitigate but I got an exception https://github.com/domaframework/doma-tools/issues/1

However I think it might have worked if the exception didn't happen as Doma Tools might be copying the resource. Not sure entirely on that but I do know the above copy resources maven plugin hack that I mentioned does not work well with Doma Tools as it causes an endless refresh cycle (doma tools sees that the resource changed which causes a rebuild which then copies the resource again ... repeat repeat. (the exception still happens regardless though as JavaCore.create(IProject) doesn't check if its a Java project).

nakamura-to commented 5 years ago

I tried Eclipse 4.12 and m2e-apt 1.5.2. They work fine with Doma 2.24.0.

The SQL files are copied to the output folder but they are located in: src/main/resources as per Maven conventions.

No. src/main/resources is not the output folder, but source folder.

In most case, the output folder is target/classes. Are the SQL files are copied to target/classes? Also, are the class files copied to same target/classes? They must be copied to same output folder. I show you my sample project structure as following:

eclipse-workspace-4_12_-_aaa_pom_xml_-_Eclipse_IDE

To check the output folder settings, go to your project Properties > Java Build Path > Source.

agentgt commented 5 years ago

No. src/main/resources is not the output folder, but source folder.

I think this is a miscommunication. What I meant is the src/main/resources get copied to target/classes. If you put resources in src/main/java it will not work without special configuration. That is what I meant.

I can show you the exact same picture you have there and I still have the red X on the dao method.

The sql files are in the target/classes (I'm seriously debating whether to send a screenshot and I will later if I can).

I'll try on a fresh project to check later tonight if it is some issue.

BTW did you try this on a multimodule maven project?

agentgt commented 5 years ago

Yes I just tried on a fresh maven multi module project and same problem. I'll put a screen shot soon of my target/classes in the navigator if you really don't believe me.

Anyway did you make sure to maven clean build through eclipse? Not the command line maven rebuild but in Eclipse do a "Alt-F5" = Maven -> Update Project.

agentgt commented 5 years ago

~~When you get a chance send me that project you made zipped up including the .classpath and .project and .settings.~~

Just paste your .classpath and .project here and I'll compare them to mine to see if that is the issue.

agentgt commented 5 years ago

Alright I figured out the issue and I can see why it probably worked for you.

Heres the deal if you touch the Dao by saving it (files marked w/ @Dao) it will find it.

However if you then "Alt-F5" = Maven -> Update Project it will say the resource isn't found.

I tested this on several Eclipses and other machines even. I can zip up a bare project.

This is most likely an Eclipse/M2E bug.

Again here are the steps to reproduce the behavior:

I urge you to try the above to make sure I'm not crazy.

Thank you so much though for your patience. I will file a bug with m2e-apt.

EDIT this is most likely the issue: https://github.com/jbosstools/m2e-apt/issues/67

nakamura-to commented 5 years ago

Again here are the steps to reproduce the behavior:

Thank you. I can reproduce the behavior.

This is most likely an Eclipse/M2E bug.

I agree with you.

After pressing *"ALT-F5" on the project, you can find that Java Build Path settings are changed as followings:

java_build_path

Try to remove the "Excluded: **" entry from src/main/resources. Then it will work fine.

I think that M2E must not insert the "Excluded: **" entry without permission.

quanghaouit commented 4 years ago

I have the same problem and here that my solution for solving it

settingdoma

nakamura-to commented 5 months ago

See https://doma.readthedocs.io/en/latest/build/#maven.

We have confirmed that Eclipse 2024-03 works with the settings provided in the link.