4
votes

Sortie de gradle de classe générée en double (build / ...) vs sortie intellij (out / ...)

J'utilise intellij (2019.1.1) pour un projet java gradle (5.4.1) et j'utilise lombok (1.18.6) pour la génération automatique de code. Intellij place les sources générées sous out / production / classes / generated / ... et gradle les place sous build/generated/sources/...

C'est bien , et j'aime bien qu'intellij garde ses propres artefacts de construction séparés des gradles, cependant, intellij semble regarder dans les deux répertoires lors de l'exécution de projets et se plaint des classes générées en double. Quelle est la meilleure pratique pour utiliser intellij avec des sources gradle et générées automatiquement? Êtes-vous:

  1. dites à intellij de sortir dans le même répertoire que gradle (ceci pourrait conduire à un comportement étrange si un processus en dehors des mises à jour intellij un fichier en construction /)
  2. dites à intellij d'effectuer toutes les tâches avec gradle (j'entends que c'est plus lent que celui d'intellij)
  3. dites à intellij d'ignorer simplement le répertoire 'build' (comment faites-vous cela? et pourquoi intellij se soucie-t-il même de 'build /' quand il sait qu'il sort à 'out /')

MISE À JOUR : pour clarifier la situation, le problème n'est PAS avec le code généré automatiquement par lombok, c'est avec hibernate-jpamodelgen. Le problème reste le même (dupliquer les sources générées) mais je tiens à préciser que ce sont les sources générées par jpamodelgen et non par lombok.

UPDATE 2 : J'ai essayé la configuration suivante dans une tentative de dire à intellij où vivent les sources générées et aussi de dire à intellij d'ignorer le répertoire de construction. Malheureusement, cela n'a pas fonctionné (toujours une erreur de classe en double sur les fichiers source générés).

    apply plugin: 'idea'
    idea {
        module {
            sourceDirs += file('out/production/classes/generated')
            generatedSourceDirs += file('out/production/classes/generated')
            excludeDirs += file('build')
        }
    }

MISE À JOUR 3 : J'ai essayé les conseils de M.Riccuiti et supprimé build /, out /, .idea /, .gradle / et réimporté le projet gradle mais intellij voit toujours les sources générées dans le répertoire build /.

 sources générées root

 paramètres du processeur d'annotation

 gradle settings

gradle runner settings


11 commentaires

J'ai eu ce même problème avec la "classe dupliquée" (classes générées pour les plugins d'annotation QueryDSL et MapStruct) après avoir migré de Gradle 4.10 vers Gradle 5.x: avant que Gradle 5.x IDEA n'utilise un autre répertoire cible pour les classes générées sous / out et étrangement ces classes n'ont pas été détectées comme dupliquées .. utilisez-vous le plugin Gradle IDEA pour configurer le projet IDEA? et avez-vous activé l'option "Déléguer la construction / le test pour créer l'outil" dans IDEA?


Je pourrais résoudre ce problème en configurant correctement les propriétés idea.module.generatedSourceDirs et idea.module.sourceDirs , en définissant la valeur sur out / production / classes / generated / .


@ M.Ricciuti Je n'ai pas activé l'outil de construction / test délégué pour construire (qui est l'option n ° 2 dans ma liste) parce que j'ai entendu dire que cela pourrait être plus lent. Je vais examiner la configuration des sourcedirs via le plugin d'idée.


Pouvez-vous fournir un tel exemple de projet? Intéressant de voir comment vous vous retrouvez avec deux répertoires de sortie de construction si vous n'utilisez pas "Déléguer" en mode Gradle.


@Andrey J'ai deux répertoires de sortie car je développe souvent à la fois à partir d'intellij et à partir du shell bash. Lorsque je ne suis pas dans un contexte d'interface utilisateur, j'utilise simplement les commandes gradle pour construire et exécuter, mais si j'ai intellij à portée de main, je l'utilise.


@Andrey J'ai un problème similaire, voir l'exemple de projet ici github.com/mricciuti/sample-springboot -gradle-idea . vous pouvez facilement reproduire le problème en commentant la configuration idea.module depuis build.gradle : après l'importation du projet dans IDEA, commencez par construire avec Gradle (depuis l'outil IDEA Gradle), puis construisez le projet (CTRL + F9)


commencez par construire avec Gradle puis je vois pourquoi vous auriez deux répertoires. Si vous ne mélangez pas Gradle et build IDE - IDE crée un seul répertoire de sortie. Pourquoi construisez-vous à la fois par Gradle et IDE?


@Andrey comme Andrew l'a déjà mentionné, parfois, vous voulez / devez effectuer certaines tâches de gradle (comme la publication, la publication ou toute autre) en dehors de l'IDEA, vous pouvez donc vous attendre à ce que le répertoire / build existe. mais il n'y a aucune raison pour que ce répertoire / build soit pris en compte par IDEA lorsque vous désactivez l'option "déléguer à Gradle".


Pour info, le problème n'est pas reproductible pour moi avec la version 2019.1.1: i.imgur.com/JDbqHjO.png < / a>


@Andrey cela semble être un comportement / bug vicieux .. Je n'ai même pas pu reproduire le problème avec mon propre projet github => J'ai fait un nouveau projet plus simple afin de le reproduire: voir github.com/mricciuti/idea-gradle-duplicated-class . Voir le README pour les étapes à reproduire


Je vous remercie! Rempli le youtrack.jetbrains.com/issue/IDEA-211818 Veuillez suivre.


3 Réponses :


1
votes

La solution que j'ai proposée dans le commentaire précédent fonctionnait bien dans IDEA 2018.3.x mais après la mise à niveau vers IDEA 2019.1, j'ai à nouveau eu cette exception de classe en double ...

Voici une solution de travail pour que cela fonctionne avec Gradle 5. x (testé avec 5.4) et IDEA 2019.1, pour implémenter votre solution n ° 3 qui, à mon avis, est la meilleure option (ne mélangez pas les répertoires de sortie générés par gradle et idée, et ne déléguez pas l'action IDEA faire Gradle)

Le point clé est d'utiliser la propriété excludeDirs de l'extension idea.module pour que IDEA ignore les sources générées gérées par Gradle sous build / generated / sources / ...

ext {
    // path to Gradle generated main sources directory
    gradleGeneratedMainSourcesDir = "$buildDir/generated/sources/annotationProcessor/java/main/"
    // path to Gradle generated test sources directory
    gradleGeneratedTestSourcesDir = "$buildDir/generated/sources/annotationProcessor/java/test/"
    // path to IDEA generated sources directory
    ideaGeneratedSourcesDir = "$projectDir/out/production/classes/generated"        
}

idea {
    module {
        // exclude main & test sources generated by Gradle from project source directories
        excludeDirs += file(gradleGeneratedMainSourcesDir)
        excludeDirs += file(gradleGeneratedTestSourcesDir)

        // include generated sources directory managed by IDEA
        sourceDirs += file(ideaGeneratedSourcesDir)
        generatedSourceDirs += file(ideaGeneratedSourcesDir)
    }
}

Voir l'exemple de projet complet basé sur cette configuration ici: https://github.com/mricciuti/sample-springboot-gradle-idea


3 commentaires

J'ai essayé et cela ne fonctionne pas. Intellij voit $ buildDir / generated / sources / annotationProcessor / java / main / comme répertoire source même s'il se trouve dans les répertoires exclus. Si j'inspecte le module dans intellij, ce répertoire est répertorié pour exclusion, mais il l'a également répertorié sous les répertoires source. J'ai l'impression que c'est une question d'ordre des opérations où intellij favorise les répertoires source par rapport aux exclusions.


Je vous suggère de réimporter complètement votre projet dans IDEA, après avoir supprimé manuellement les répertoires .idea /, .gradle /, / out et / build. Ensuite, commencez par construire avec Gradle (à partir de l'outil IDEA gradle), et vérifiez que $ buildDir / generated / sources / annotationProcessor / java / main n'est pas marqué comme répertoire "source générée" dans l'arborescence du répertoire du projet. Seulement après, faites le projet construit par IDEA. J'espère que cela t'aides.


@ M.Ricciuti Désolé de vous avoir «attiré», mais dans un grand projet, nous avons aussi beaucoup de problèmes avec les méta-modèles générés qui ne sont pas trouvés et qui sont en effet créés par jpamodelgen. J'ai remarqué que notre projet ajoute un répertoire «généré» sous «build / generated / sources / annotationProcessor / java / main /». Ce qui semble être notre attente des sources. Si je change tous ces paramètres sur l'intelliJ principal, c'est toujours une erreur sur nous. Nous avons délégué gradle à gradle (pas à intelliJ) et nous n'avons vraiment pas besoin que les sources générées soient en «out». Je suis tellement confus.



2
votes

Voici une approche qui a finalement fonctionné pour moi. L'astuce consiste à remarquer que lorsque gradle génère les classes, il les place dans:

build\generated\sources\annotationProcessor\java\main\generated\com...

mais intellij a le répertoire des sources de production défini sur "généré" dans ce cas, les sources vont à:

build\generated\sources\annotationProcessor\java\main\com...

si vous compilez d'abord avec gradle puis utilisez idea, vous obtenez les deux, ce qui pose le problème!

Pour résoudre ce problème, remplacez "generated "et" generated_test "dans la configuration des processeurs d'annotation intellij" répertoire des sources de production "et" répertoire des sources de test "avec juste un" / "cela fait à la fois gradle et intellij générer les sources dans le répertoire SAME, en se remplaçant si nécessaire. Assurez-vous également que «stocker les sources générées par rapport à» est défini sur «racine du contenu du module» et RECONSTRUISEZ l'application pour effacer toutes les autres sources.


2 commentaires

c'est vrai si vous voulez que gradle et intellij soient tous les deux sortis vers / build. J'essaie de séparer la sortie intellij (/ out) et la sortie gradle (/ build).


Je pense que vous pouvez obtenir ce genre de comportement simplement en "excluant" le répertoire de construction entièrement en utilisant la fonction "marquer le répertoire comme .." dans intellij et en définissant la sortie d'annotation du compilateur sur le répertoire "sortie de construction". Cela devrait éviter d'inclure quoi que ce soit du répertoire "build". Je crois également que le signal "exclure" doit rester intact même lors de la réimportation du fichier gradle.build. J'ai été fortement découragé d'utiliser le plugin idea-gradle et j'ai constaté qu'essayer de jouer avec la configuration par défaut de l'idée provoque plus de maux de tête que jamais prévu.



0
votes

Vous pouvez accéder aux paramètres IntelliJ (Préférences):

Préférences | Construction, exécution, déploiement | Outils de construction | Gradle | Coureur

Ensuite, cochez la case Déléguer l'action de construction / exécution de l'EDI à Gradle

Enfin, vous nettoyez et reconstruisez à nouveau. Les problèmes seront résolus.


0 commentaires