kelemen / netbeans-gradle-project

This project is a NetBeans plugin able to open Gradle based Java projects. The implementation is based on Geertjan Wielenga's plugin.
170 stars 57 forks source link

Generated sources not recognised by NB with Gradle build #332

Closed ghost closed 7 years ago

ghost commented 7 years ago

Hello,

I am using NB 8.2 on Ubuntu 16.04 and Gradle 3.4.1. I also use Maven 3.3.9 to build the exact same project.

I have generated sources from hibernate-jpamodelgen processor. My Maven configuration generete these sources in a target/generated-sources/plugin-name as instructed in NB project->properties->sources window in a MAven project. Works like a charm.

When I use Gradle, I simply add the processor to the dependencies and the sources are generated in a Generated section of the project tree in a congruent package (ie the ...domain package). The problem is that Netbeans does not recognise these sources and shows error badges everywhere even if the build works just fine.

The most annoying effect is that the auto import does not work.

image

Thanks for your support. Jacques

kelemen commented 7 years ago

Given what you have said, I would guess that you did not add the required dependencies to the compile time classpath of the generated sources (generatedCompile or generatedCompileOnly). To tell you more, I would have to see a build of yours (it only needs to reproduce this issue). In general, generated sources are not treated different to any other source sets, I'm unaware of any issues with it, and this project (NetBeans Gradle plugin) also uses different source sets with different dependencies.

ghost commented 7 years ago

Thanks for the quick answer,

I am more familiar with Maven but I want to learn to use Gradle. The sourceSet concept seems easy to grasp at first sight but we know where the devil lies and concept and usage documentation available on the subject is quite scarce.

I attach the build.gradle which I am sure is really basic and miss lots of things. I have tried many approaches with configuring sourceSets but all failed miserably. The frustrating part is that, with this build, I don't see the generated Classes anywhere but yet, the build passes, the Classes are compiled and saved in the build/classes along the other domain classes... and still, NB does not recognize them.

On the Maven side, I use a org.bsc.maven - maven-processor-plugin and the NB default for generated sources by storing the generated classes in the "generated-sources/hibernate-jpamodelgen" directory and NB picks them up no sweat. I just can't figure out the equivalent configuration with Gradle.

Thanks for your help.

Jacques

[image: Inline image 1]

On Wed, Apr 12, 2017 at 4:38 PM, Attila Kelemen notifications@github.com wrote:

Given what you have said, I would guess that you did not add the required dependencies to the compile time classpath of the generated sources ( generatedCompile or generatedCompileOnly). To tell you more, I would have to see a build of yours (it only need to reproduce this issue). In general, generated sources are not treated different to any other source sets, I'm unaware of any issues with it, and this project (NetBeans Gradle plugin) also uses different source sets with different dependencies.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-293700431, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2VxiyOVkDkMXUSUvoJ7qvYJV5jjSks5rvTY8gaJpZM4M63Ew .

Executing: gradle clean build Arguments: [-u]

:clean Note: Hibernate JPA 2 Static-Metamodel Generator 5.2.9.Final :compileJava :processResources :classes :findMainClass :jar :bootRepackage :assemble Note: Hibernate JPA 2 Static-Metamodel Generator 5.2.9.Final :compileTestJava :processTestResources UP-TO-DATE :testClasses :test 2017-04-13 09:18:41.976 INFO 6113 --- [ Thread-11] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext@5c591648: startup date [Thu Apr 13 09:18:40 EDT 2017]; root of context hierarchy 2017-04-13 09:18:41.980 INFO 6113 --- [ Thread-9] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@185c57d0: startup date [Thu Apr 13 09:18:36 EDT 2017]; root of context hierarchy 2017-04-13 09:18:42.013 INFO 6113 --- [ Thread-6] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@21a3bb4a: startup date [Thu Apr 13 09:18:32 EDT 2017]; root of context hierarchy 2017-04-13 09:18:42.037 INFO 6113 --- [ Thread-6] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2017-04-13 09:18:42.039 INFO 6113 --- [ Thread-9] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' :check :build

BUILD SUCCESSFUL

Total time: 14.637 secs

kelemen commented 7 years ago

I can't see your build.gradle but I have a guess what your problem is. As is the current release, the source roots are not automatically refreshed. That is, currently you have to reload the project for it. However, if you build this plugin from the sources (it should build out of the box), it is now fixed and will pick up the the source root as soon as it is physically available.

Anyway, can you send a link to your build.gradle? Possibly as a gist or you can send me a separate email (if you prefer that way).

ghost commented 7 years ago

Here is a gist link.

https://gist.github.com/ledj0304/72292153b54d622de196ad2005e4137d

I left a comment as to my modest progress.

J

jcq@ledx.com

On Thu, Apr 13, 2017 at 12:24 PM, Attila Kelemen notifications@github.com wrote:

I can't see your build.gradle but I have a guess what your problem is. As is the current release, the source roots are not automatically refreshed. That is, currently you have to reload the project for it. However, if you build this plugin from the sources (it should build out of the box), it is now fixed and will pick up the the source root as soon as it is physically available.

Anyway, can you send a link to your build.gradle? Possibly as a gist https://gist.github.com or you can send me a separate email (if you prefer that way).

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-293948335, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2SGcw7jWB9lEk9HZQZXVV5sRwlYZks5rvkxKgaJpZM4M63Ew .

kelemen commented 7 years ago

I have adjusted your scripts and though I have not tested it, it should work: https://gist.github.com/anonymous/bcffcb026bf12e03662e9c158df0383d

Note that I have removed some parts to reduce noise. Also, there is a common mistake (for newcomers) in the script you have linked. When you are writing something like this:

task sayHello {
    println "Hello"
}

You are not defining a task action because the parts between the braces is the configuration of the task (and not the action). This will print "Hello" regardless if you run the task or not. Instead, you have to write this:

task sayHello {
    doLast {
        println "Hello"
    }
}
ghost commented 7 years ago

Thanks Attila.

This version helped but my Classes_ are not generated even is the build completes. One thing I just don't understand is the following message on each build run even when I delete all the destination directories from the previous run

:publish:compileJpamodelgenJava UP-TO-DATE :publish:processJpamodelgenResources UP-TO-DATE :publish:jpamodelgenClasses UP-TO-DATE

How could these classes be Up-To-Date when their sources are not generated anywher let alone their compiled versions. On the Maven side, all sources are generated in "target/generated-sources/hibernate-jpamodelgen/..." and their compiled versions in the "target/classes"

I appreciate your help very much and understand that the problem may be elsewhere of the netbeans plugin.

Thanks for all

J

On Thu, Apr 13, 2017 at 1:21 PM, Attila Kelemen notifications@github.com wrote:

I have adjusted your scripts and though I have not tested it, it should work: https://gist.github.com/anonymous/bcffcb026bf12e03662e9c158df0383d

Note that I have removed some parts to reduce noise. Also, there is a common mistake (for newcomers) in the script you have linked. When you are writing something like this:

task sayHello { println "Hello" }

You are not defining a task action because the parts between the braces is the configuration of the task (and not the action). This will print "Hello" regardless if you run the task or not. Instead, you have to write this:

task sayHello { doLast { println "Hello" } }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-293966026, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2cVcD_Cw0dFZyjKSJjSwtV1b6UP0ks5rvlmBgaJpZM4M63Ew .

kelemen commented 7 years ago

For some reason, I thought that you want to generate the sources manually by running the generateMetamodel task. If you want it to run automatically, then just add generateMetamodel.dependsOn compileJava. Also, if you want to change the source root of you source set you can also add sourceSets.jpamodelgen.java.srcDirs = [new File(buildDir, 'generated-sources/jpamodelgen')] (of course, you can nest these calls into the appropriate configuration blocks, instead of writing out the whole chain of calls).

UP-TO-DATE is written because there are no sources in the source root, since I assumed you are generating it manually. Also, I would like to repeat that with the current version of this plugin you might be forced to reload the project (from the project's context menu) if you are not seeing the generated source folder in the project view (you can build this plugin from the sources or wait for the next release to have automatic source root creation detection).

kelemen commented 7 years ago

Sorry, instead of generateMetamodel.dependsOn compileJava, you have to write the reverse: compileJava.dependsOn generateMetamodel.

ghost commented 7 years ago

Yes, I do reload every time I change a comma in the gradle.build ;-). I just realized that -i flag provides lots of info and you are right about the source files that are not reached so the processor assume that there are none and outputs the UP-TO-DATE message (which to my opinion should be NO-SOURCE instead).

I am searching for a solution to this problem... I just couldn't imagine this without Google.

J

On Thu, Apr 13, 2017 at 6:26 PM, Attila Kelemen notifications@github.com wrote:

For some reason, I thought that you want to generate the sources manually by running the generateMetamodel task. If you want it to run automatically, then just add generateMetamodel.dependsOn compileJava. Also, if you want to change the source root of you source set you can also add sourceSets.jpamodelgen.java.srcDirs = [new File(buildDir, 'generated-sources/jpamodelgen')] (of course, you can nest these calls into the appropriate configuration blocks, instead of writing out the whole chain of calls).

UP-TO-DATE is written because there are no sources in the source root, since I assumed you are generating it manually. Also, I would like to repeat that with the current version of this plugin you might be forced to reload the project (from the project's context menu) if you are not seeing the generated source folder in the project view (you can build this plugin from the sources or wait for the next release to have automatic source root creation detection).

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-294037638, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2RMjLQp4wK_H_AaZP3gVl_HMgaRwks5rvqEfgaJpZM4M63Ew .

kelemen commented 7 years ago

You are probably using an older version Gradle. The "NO-SOURCE" state is a new thing (try Gradle 3.5).

I meant, you have to reload if you run a task which generated a new source folder with the latest release. Even if you didn't change the script at all. Anyway, did those task dependencies and the source root declaration helped you?

ghost commented 7 years ago

I'm using 3.4.1. The NO-SOURCE thing I read on some Googling page. I'm out breeding some fresh air after this miserable day.

The thing I cannot figure out is how to configure the generateMeta... task source directory (ies). No matter I do, I still get the "no source configured" so the task is nevr executed.

Hey, again, I truly appeciate what you do for me. Don't ever hesitate to ping me if you need help of any kind.

J

On Apr 13, 2017 7:22 PM, "Attila Kelemen" notifications@github.com wrote:

You are probably using an older version Gradle. The "NO-SOURCE" state is a new thing (try Gradle 3.5).

I meant, you have to reload if you run a task which generated a new source folder with the latest release. Even if you didn't change the script at all. Anyway, did those task dependencies and the source root declaration helped you?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-294046293, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2fn7v3-daPAXNkGzHvz6PeuZp-foks5rvq4zgaJpZM4M63Ew .

kelemen commented 7 years ago

I have played with this a little and this worked for me (omitted the less relevant parts)

configurations {
    jpamodelgen.extendsFrom compile
}

def jpaGenOutput = new File(buildDir, 'generated-sources/jpamodelgen')
sourceSets.main.java.srcDir jpaGenOutput

tasks.withType JavaCompile, {
    if (it.name != 'generateMetamodel') {
        options.encoding = 'UTF-8'
        options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
    }
}

task generateMetamodel(type: JavaCompile) {
    source = sourceSets.main.java
    classpath = configurations.jpamodelgen
    options.compilerArgs = [
        '-proc:only',
        '-processor',
        'org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor'
    ]
    destinationDir = jpaGenOutput
}

compileJava.dependsOn generateMetamodel

dependencies {
    compile('org.springframework.boot:spring-boot-starter-data-jpa')
    compile('org.flywaydb:flyway-core')
    compile('org.springframework.boot:spring-boot-starter-groovy-templates')
    compile('org.springframework.boot:spring-boot-starter-security')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.flywaydb:flyway-gradle-plugin:3.2.1')
    runtime('org.hsqldb:hsqldb')
    runtime('mysql:mysql-connector-java')
    compileOnly('org.springframework.boot:spring-boot-configuration-processor')
    compile('org.projectlombok:lombok')
    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.powermock:powermock-module-junit4:1.6.6')
    testCompile('org.powermock:powermock-api-mockito:1.6.6')

    compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final'
    jpamodelgen ('org.hibernate:hibernate-jpamodelgen:5.2.9.Final')
}

I have removed the use of multiple source sets to allow both source roots to reach each other. This actually, should work like the Maven counter part.

ghost commented 7 years ago

V for victory!!!!

It works exactly as you said and Netbeans recognizes the generated files.

There is a llllot for me to learn from this adventure and you have been a great (and very patient) teacher. I had some Groovy experience and fiddled with Gradle a bit before but this makes me realize the deepness of this build tool. It's quite complex but it is made to do complex things too... so it's fair and I will invest more time in learning it.

Thanks again for the support you gave me and again, don't hesitate if I can help you for testing, writing or anything within my scope of competence. I'll be happy to return the service.

I don't know what time it is for you so...good night

J

On Thu, Apr 13, 2017 at 8:51 PM, Attila Kelemen notifications@github.com wrote:

I have played with this a little and this worked for me (omitted the less relevant parts)

configurations { jpamodelgen.extendsFrom compile } def jpaGenOutput = new File(buildDir, 'generated-sources/jpamodelgen') sourceSets.main.java.srcDir jpaGenOutput

tasks.withType JavaCompile, { if (it.name != 'generateMetamodel') { options.encoding = 'UTF-8' options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" } }

task generateMetamodel(type: JavaCompile) { source = sourceSets.main.java classpath = configurations.jpamodelgen options.compilerArgs = [ '-proc:only', '-processor', 'org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor' ] destinationDir = jpaGenOutput }

compileJava.dependsOn generateMetamodel

dependencies { compile('org.springframework.boot:spring-boot-starter-data-jpa') compile('org.flywaydb:flyway-core') compile('org.springframework.boot:spring-boot-starter-groovy-templates') compile('org.springframework.boot:spring-boot-starter-security') compile('org.springframework.boot:spring-boot-starter-web') compile('org.flywaydb:flyway-gradle-plugin:3.2.1') runtime('org.hsqldb:hsqldb') runtime('mysql:mysql-connector-java') compileOnly('org.springframework.boot:spring-boot-configuration-processor') compile('org.projectlombok:lombok') testCompile('org.springframework.boot:spring-boot-starter-test') testCompile('org.powermock:powermock-module-junit4:1.6.6') testCompile('org.powermock:powermock-api-mockito:1.6.6')

compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final'
jpamodelgen ('org.hibernate:hibernate-jpamodelgen:5.2.9.Final')

}

I have removed the use of multiple source sets to allow both source roots to reach each other. This actually, should work like the Maven counter part.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-294058244, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2ZeCRWuGwkbXeXlxjDaFi3hj1mOJks5rvsMegaJpZM4M63Ew .

kelemen commented 7 years ago

No problem, I'm glad I was able to help.

As for Gradle, what you have to know in this case is what is a SourceSet and source roots within it: The SourceSet is simply a collection of source files sharing the same dependencies and compile in a single compilation step. And a source roots are just separate directories within a SourceSet.

By the way, my favourite feature of Gradle is something many ignore: You can create a directory within the root project named buildSrc and that is considered a single Groovy project (you should add an appropriate build.gradle). This project is compiled before the build and is available for all the build scripts. So, you can code your build in pure Java as well (mixed with Groovy code) and even declare your own plugin which you can use in all the projects of your multi-project build. I think buildSrc is a much better alternative to scattering your build across .gradle files.

ghost commented 7 years ago

Hello Attila,

I am an old goat over 60 that does software dev. since the mid 80's. I'm a Java fan since the early 2000 but has been mostly away from coding since 2010 or so (working for large consulting firms). I lead developers teams for many years and embrace open source at the same time as I became Java. I am a total autodidact and I have never sat in a Computer Science class except for few invitations as a presenter (in which I didn't sat, only stood up :-).

Yesterday I bought 3 books about Gradle and read few chapters before going to sleep. One of them was about sourceset and you know what? Your single sentence explanation provides a better understanding about sourceSet than the whole chapter I read... and it was very well written (TIm Berglund). I don't know if you teach but you certainly are a natural pedagogue. It was also evident during our exchange as you always took care to explain the technical logic and rationale behind your suggestions. And one other thing, you also are as passionate as could be about the work you do... it also shows in your writings.

It's funny, about the buildSrc directory... it was mentioned in my readings yesterday and lots of ideas about this popped through my mind. Opens a lot of possibilities to encapsulate complexity and move it away from the front seat user.

Always a pleasure to exchange with you,

Have a good day,

J

On Fri, Apr 14, 2017 at 7:34 AM, Attila Kelemen notifications@github.com wrote:

No problem, I'm glad I was able to help.

As for Gradle, what you have to know in this case is what is a SourceSet and source roots within it: The SourceSet is simply a collection of source files sharing the same dependencies and compile in a single compilation step. And a source roots are just separate directories within a SourceSet.

By the way, my favourite feature of Gradle is something many ignore: You can create a directory within the root project named buildSrc and that is considered a single Groovy project (you should add an appropriate build.gradle). This project is compiled before the build and is available for all the build scripts. So, you can code your build in pure Java as well (mixed with Groovy code) and even declare your own plugin which you can use in all the projects of your multi-project build. I think buildSrc is a much better alternative to scattering your build across .gradle files.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/kelemen/netbeans-gradle-project/issues/332#issuecomment-294139611, or mute the thread https://github.com/notifications/unsubscribe-auth/AF1Q2Qe3RPKqn0zuilSWAsiVc7KU9MQRks5rv1nQgaJpZM4M63Ew .

kelemen commented 7 years ago

Thank you, it is motivating to hear because I do have the "secret" desire to explain math to young (about 14 year olds) children who claim to be stupid for math but otherwise seem to manage. Because I firmly believe that from all the subjects math is taught the worst and is simply misrepresented.

JustGregory-zz commented 7 years ago

@ledj0304 Pleased to meet you too. I, as well, am rather self-taught, and though I'm about a couple decades younger than you I definitely got my start in Java about a decade earlier than you. That said, I've learned the most about Java development from others the most in recent years (Attila naturally being one person I admire for what has been done here).

Regarding Attila's one sentence providing a much simpler definition than a whole book chapter does, I have often found this to be the truth as well. Book-authors, often paid for wordy-ness, tend to "bloat" the descriptions of things that could and should be much simpler. That's kind of why a lot of people go to ask-sites like StackExchange to obtain an answer, at least one not so wordily drawn out as from a textbook. -- I wouldn't blame the book authors, I know they need to put food on the table as well, but the chapter concept really does the learning person a disservice sometimes. You get the picture.

(But don't throw the books out; they're still good for review later, as you are learning; sometimes after working on a project you may look back at a textbook and gain a sudden new appreciation at what what actually being said on the page, something that perhaps you didn't glean at the first read-through. Attila, can I assume the same is true for teaching mathematics? Students you have helped go back and reading the textbooks suddenly understand after solving math problems?)

kelemen commented 7 years ago

I don't think book authors have such intention (not usually at least), they actually have a limited number of pages they are allowed to write and struggle to be within that limit. In my opinion it gets bloated for different reasons: They must appeal to a wide range of audience and can't get immediate feedback as they write the book (also, review is just too late and reviewers are usually experts on the subject). Also, books want to be very precise, so they must define and operate with abstract concepts and it is rather easy to get lost on what is the core idea (and there is almost always a simple idea behind it as the creator was a human who is not infinitely clever). With math, the problem is deeper in my opinion, because what is taught is to follow some made up rules and students will just learn how to go through the motions. This makes people think that math is a super complex thing created and understood by god like entities. Despite the fact, that math is stupidly simple (it wouldn't work otherwise).

Anyway, I think we are little off topic and shouldn't spam those who are notified for every message :). If it is not really related to the issue in the topic, you can drop me an email and I'm more than happy to answer. If it is a plugin/Gradle related question, you can also open a separate issue.