Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide option for querydsl-maven-plugin to produce binary Q-classes #402

Closed
matthewadams opened this issue Apr 23, 2013 · 18 comments
Closed

Provide option for querydsl-maven-plugin to produce binary Q-classes #402

matthewadams opened this issue Apr 23, 2013 · 18 comments
Assignees
Milestone

Comments

@matthewadams
Copy link
Contributor

@matthewadams matthewadams commented Apr 23, 2013

If you're using binary weaving (like aspectj) to compile your entity classes, then you're most likely using one of querydsl-maven-plugin's export goals during maven's process-classes phase to generate Q-class sources. That's all fine & dandy until you need to compile the Q-class sources, which you kind of always need to do.

You can't use maven-compiler-plugin at the process-classes phase to compile because you can't replace its compileSourceRoots property, and you can't use build-helper-maven-plugin to simply add the directory into which you had querydsl-maven-plugin generate the Q-class sources because, well, the compiler is javac and it barfs because it doesn't know about fields introduced by your weaving tool (aspectj).

If querydsl-maven-plugin could either produce binary classes or compile the generated Q-class source files by default into target/classes, I wouldn't have to fight with maven-compiler-plugin.

I've also tried configuring maven-antrun-plugin to use ant's <javac> task (as well as <exec executable="javac">), but that is failing with NPE for other reasons that I can't figure out yet.

Even if I could figure out the cause/fix or workaround for invoking javac manually, it's still inconvenient for users of querydsl-maven-plugin to have to deal with that. If the plugin could compile Q-class sources or generate binary Q-class .class files, it would be extremely convenient for the plugin's users.

As for compiler settings, I'm not sure what they should be. Perhaps they should default to whatever the current maven project's relevant compiler settings are (source, target, etc) and the plugin should allow the user to specify or override them in querydsl-maven-plugin's <configuration> section using settings that are similar or even identical to maven-compiler-plugin's <configuration> settings.

@ghost ghost assigned timowest Apr 24, 2013
@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 24, 2013

My rather undesirable workaround is to create another maven module next to my domain module, with a pom like the following that uses a relative path for its sourceDirectory. While this works, I think it's undesirable because it adds another artifact to my dependencies when I feel that the Q-classes should go into the domain artifact and because I don't really think it's a best practice to have a maven pom refer to a directory outside of its directory tree, let alone one that is in the target directory of another module.

<project ...>
    ...
    <dependencies>
        <!-- the foundation-domain module is next to this module in a directory named "domain" -->
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>foundation-domain</artifactId>
            <version>${project.parent.version}</version>
        </dependency>
    </dependencies>
    ...
    <build>
        <sourceDirectory>../domain/target/generated-sources/querydsl</sourceDirectory>
    </build>
timowest added a commit that referenced this issue Apr 24, 2013
@timowest
Copy link
Member

@timowest timowest commented Apr 24, 2013

Could you try with the latest snapshot if the additions work for you? I added the following new options

  • boolean compile
  • Map<String, String> compilerOptions
@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 24, 2013

Looks like not. The plugin is seeing the compile flag ok and entering AbstractExporterMojo#compile(Set<File>), then nothing seems to happen. No Q*.class files appear in target/classes or anywhere else that I can find. Plugin reports success:

...
[INFO] 
[INFO] --- querydsl-maven-plugin:3.1.1:jpa-export (generate-querydsl-classes) @ foundation-jpa-test-client-domain ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:26.515s
[INFO] Finished at: Wed Apr 24 14:35:50 CDT 2013
[INFO] Final Memory: 13M/81M
[INFO] ------------------------------------------------------------------------
matthew@newt:~/Documents/foundation/foundation/test-client/jpa/domain [dev] 
$ find ./target -name 'Q*.class'
matthew@newt:~/Documents/foundation/foundation/test-client/jpa/domain [dev]

I grabbed the latest source & tried to debug. I couldn't build from querydsl-root with mvn -Pjenkins,all -DskipTests=true clean install due to a compilation error:

...
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /Users/matthew/Documents/querydsl/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/AbstractHibernateQuery.java:[57,17] types com.mysema.query.jpa.JPAQueryBase<Q> and com.mysema.query.jpa.JPAQueryBase<Q> are incompatible; both define where(com.mysema.query.types.Predicate[]), but with unrelated return types
[ERROR] /Users/matthew/Documents/querydsl/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQuery.java:[30,14] types com.mysema.query.jpa.hibernate.AbstractHibernateQuery<com.mysema.query.jpa.hibernate.HibernateQuery> and com.mysema.query.jpa.hibernate.AbstractHibernateQuery<com.mysema.query.jpa.hibernate.HibernateQuery> are incompatible; both define where(com.mysema.query.types.Predicate[]), but with unrelated return types
[ERROR] /Users/matthew/Documents/querydsl/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java:[28,14] types com.mysema.query.jpa.impl.AbstractJPAQuery<com.mysema.query.jpa.impl.JPAQuery> and com.mysema.query.jpa.impl.AbstractJPAQuery<com.mysema.query.jpa.impl.JPAQuery> are incompatible; both define where(com.mysema.query.types.Predicate[]), but with unrelated return types
[INFO] 3 errors 
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Querydsl .......................................... SUCCESS [1.075s]
[INFO] Querydsl - Core module ............................ SUCCESS [17.692s]
[INFO] Querydsl - Codegen module ......................... SUCCESS [4.126s]
[INFO] Querydsl - APT support ............................ SUCCESS [13.275s]
[INFO] Querydsl - Collections support .................... SUCCESS [2.837s]
[INFO] Querydsl - SQL support ............................ SUCCESS [5.347s]
[INFO] Querydsl - SQL codegen support .................... SUCCESS [3.521s]
[INFO] Querydsl - Maven plugin ........................... SUCCESS [2.455s]
[INFO] Querydsl - JPA support ............................ FAILURE [20.891s]
[INFO] Querydsl - JPA Codegen support .................... SKIPPED
[INFO] Querydsl - JDO support ............................ SKIPPED
[INFO] Querydsl - Lucene support ......................... SKIPPED
[INFO] Querydsl - Hibernate Search support ............... SKIPPED
[INFO] Querydsl - Mongodb support ........................ SKIPPED
[INFO] Querydsl - Scala support .......................... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:11.595s
[INFO] Finished at: Wed Apr 24 14:25:26 CDT 2013
[INFO] Final Memory: 31M/102M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.0:compile (default-compile) on project querydsl-jpa: Compilation failure: Compilation failure:
[ERROR] /Users/matthew/Documents/querydsl/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/AbstractHibernateQuery.java:[57,17] types com.mysema.query.jpa.JPAQueryBase<Q> and com.mysema.query.jpa.JPAQueryBase<Q> are incompatible; both define where(com.mysema.query.types.Predicate[]), but with unrelated return types
[ERROR] /Users/matthew/Documents/querydsl/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQuery.java:[30,14] types com.mysema.query.jpa.hibernate.AbstractHibernateQuery<com.mysema.query.jpa.hibernate.HibernateQuery> and com.mysema.query.jpa.hibernate.AbstractHibernateQuery<com.mysema.query.jpa.hibernate.HibernateQuery> are incompatible; both define where(com.mysema.query.types.Predicate[]), but with unrelated return types
[ERROR] /Users/matthew/Documents/querydsl/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java:[28,14] types com.mysema.query.jpa.impl.AbstractJPAQuery<com.mysema.query.jpa.impl.JPAQuery> and com.mysema.query.jpa.impl.AbstractJPAQuery<com.mysema.query.jpa.impl.JPAQuery> are incompatible; both define where(com.mysema.query.types.Predicate[]), but with unrelated return types
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
[ERROR] 
[ERROR] After correcting the problems, you can resume the build with the command
[ERROR]   mvn <goals> -rf :querydsl-jpa
matthew@newt:~/Documents/querydsl/querydsl-root [master] 

Any ideas?

@timowest
Copy link
Member

@timowest timowest commented Apr 24, 2013

Any ideas?

Yes, this is a JDK 6 issue. It's a bug in the javac compiler that has been fixed in JDK 7. Querydsl builds are still JDK 6 compatible, but the build has to be performed with JDK 7.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 24, 2013

Ok, I'll try with JDK 7 & see what I can figure out.

@timowest
Copy link
Member

@timowest timowest commented Apr 24, 2013

I just realized that I should probably put the compilation functionality into a separate goal. I will do that refactoring tomorrow.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 24, 2013

Ok, the plugin appears to be working ok -- I'm getting Q-.class files now in the right place. I was having some kind of 3.1.1/3.1.2.BUILD-SNAPSHOT version issues, but I resolved them.

FYI, the output I'm getting now is below. Notice that -source & -target appear to be 1.7 (inferred from the warnings below), but my maven project settings are calling for 1.6. As I suggested, perhaps the default compiler settings or options should be gleaned from the user's current maven project, and be overridden by compilerOptions. If you do that, then you'd probably want to exclude src/main/java & any other main source folders, though, and maybe put target/classes (or ${project.build.outputDirectory}) on the classpath for the Q-class compilation (unless they're never necessary).

It also looks like I need to turn off annotation processors, too. I'm wondering if turning them off by default is an appropriate setting for the plugin. Seems reasonable, but if the user has defined some annotation processors, maybe he wants them to run. Perhaps that option should be required and not have a default value. WDYT?

[INFO] --- querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:jpa-export (generate-querydsl-classes) @ foundation-jpa-test-client-domain ---
[INFO] Generating sources
[INFO] Compiling
warning: Supported source version 'RELEASE_6' from annotation processor 'org.datanucleus.jdo.query.JDOQueryProcessor' less than -source '1.7'
warning: Supported source version 'RELEASE_6' from annotation processor 'org.datanucleus.jpa.query.JPACriteriaProcessor' less than -source '1.7'
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 warnings
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.356s
[INFO] Finished at: Wed Apr 24 15:57:46 CDT 2013
[INFO] Final Memory: 23M/229M
[INFO] ------------------------------------------------------------------------```
@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 24, 2013

I don't know that you need a separate compile-exported-sources-ish goal. It seems natural at first glance to separate the goals, but it's going to require more lines in the already verbose pom.xml, and I think a very common use case will be to just compile them whenever a *-export goal is specified. In fact, I'd even go so far as to say that's appropriate default behavior given the scenarios that call for the use of *-export. :)

@timowest
Copy link
Member

@timowest timowest commented Apr 25, 2013

The configuration for the goals can be shared, so the extra lines needed are not much, I guess one line will do it. It makes the separation of the concerns more clear.

@timowest
Copy link
Member

@timowest timowest commented Apr 25, 2013

Could you try again with the compile goal? I added some of the maven-compiler-plugin options and proc:none should skip APT.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 26, 2013

Ok, I tried but it looks like the only path being returned by buildCompileClasspath() is target/classes. None of the actual project dependencies are making it to the compiler, so I get errors like this:

/Users/matthew/Documents/foundation/foundation/test-client/jpa/domain/target/generated-sources/querydsl/app/domain/model/QGeneration.java:3: error: package com.mysema.query.types does not exist
import static com.mysema.query.types.PathMetadataFactory.*;

Not sure what's going on here, as I'd expect MavenProject#getCompileClasspathElements() to just work. Looks like MavenProject#getArtifacts() is returning an empty set.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 26, 2013

GenericExporterMojo calls the folder into which Q-classes are written targetFolder, which makes sense in that context. I'd recommend a name change for CompileMojo's targetFolder: it should be called sourceFolder, qSourceFolder or similar, so the user doesn't confuse it with target/classes, because in CompileMojo's context, which is compilation, target implies where the .class files go. WDYT?

@timowest
Copy link
Member

@timowest timowest commented Apr 26, 2013

The CompileMojo has now proper dependency resolution and I renamed targetFolder to sourceFolder.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 26, 2013

Made some progress, but now getting new error message:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.768s
[INFO] Finished at: Fri Apr 26 14:55:37 CDT 2013
[INFO] Final Memory: 19M/234M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile (compile-querydsl-classes) on project foundation-jpa-test-client-domain: Execution compile-querydsl-classes of goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile failed: No basedir set -> [Help 1]

Invoking maven with -X yields:

[ERROR] Failed to execute goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile (compile-querydsl-classes) on project foundation-jpa-test-client-domain: Execution compile-querydsl-classes of goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile failed: No basedir set -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile (compile-querydsl-classes) on project foundation-jpa-test-client-domain: Execution compile-querydsl-classes of goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile failed: No basedir set
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:225)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution compile-querydsl-classes of goal com.mysema.querydsl:querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile failed: No basedir set
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:110)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 19 more
Caused by: java.lang.IllegalStateException: No basedir set
    at org.codehaus.plexus.util.DirectoryScanner.scan(DirectoryScanner.java:286)
    at com.mysema.query.maven.CompileMojo.getJavaFiles(CompileMojo.java:171)
    at com.mysema.query.maven.CompileMojo.execute(CompileMojo.java:187)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    ... 20 more
@timowest
Copy link
Member

@timowest timowest commented Apr 26, 2013

Does you configuration have the sourceFolder set? I will add the requires flags later, when this stabilizes.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 26, 2013

Ooh -- may have forgotten that. I'll check as soon as I'm back at desk.

Sent from my iPhone

On Apr 26, 2013, at 3:01 PM, "Timo Westkämper" notifications@github.com
wrote:

Does you configuration have the sourceFolder set? I will add the requires
flags later, when this stabilizes.


Reply to this email directly or view it on
GitHubhttps://github.com//issues/402#issuecomment-17096967
.

@matthewadams
Copy link
Contributor Author

@matthewadams matthewadams commented Apr 27, 2013

Yep -- forgot to change my pom to use sourceFolder. I updated & things look good:

...
[INFO] --- querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:jpa-export (generate-querydsl-classes) @ foundation-jpa-test-client-domain ---
[INFO] 
[INFO] --- querydsl-maven-plugin:3.1.2.BUILD-SNAPSHOT:compile (compile-querydsl-classes) @ foundation-jpa-test-client-domain ---
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 5.196s
[INFO] Finished at: Fri Apr 26 19:42:50 CDT 2013
[INFO] Final Memory: 30M/225M
[INFO] ------------------------------------------------------------------------

I have compiled Q-classes in target/classes right alongside my entity classes. Excellent. 👍

timowest added a commit that referenced this issue Apr 27, 2013
timowest added a commit that referenced this issue Apr 27, 2013
@timowest
Copy link
Member

@timowest timowest commented May 27, 2013

Released in 3.2.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants