10
votes

Comment lire le fichier de SRC / Main / Ressources avec le processeur d'annotation?

J'ai un processeur d'annotation simple qui doit lire un fichier de configuration du même projet que les classes annotées. Exemple de structure: xxx

dans le processeur d'annotation, j'essaie de lire le fichier: xxx

mais il jette filenotfoundexception . J'ai également essayé d'autres chemins, tels que ../ ressources / config.json , (qui lance nom relatif non valide: ../ Ressources / config.json ). Et j'ai essayé de mettre le fichier de configuration dans src / main / java (et même src / main / java / mon / package ), ce que je n'aime pas, que je n'aime pas, mais Cela jette également toujours filenotfoundexception .

Cela aiderait déjà si je pouvais obtenir filer.getresource () pour me dire où il cherche. Pour le savoir, j'ai essayé de générer un fichier: xxx

généré dans myProject / construction / classes / principale / mannequin . Malheureusement, je ne peux pas générer dans source_path , afin que cela n'aide pas à la découvrir.


6 commentaires

Je ne connais pas l'API que vous utilisez, mais si cela prend le chemin source comme base, cela résoudrait à Main / Java / My / Package / Config.json , alors monte Une fois avec .. ne suffirait pas. Vous pouvez essayer de mettre la ressource dans le même package que le fichier source. i.e principale / ressources / mon / package / config.json .


Je ne sais pas pourquoi le chemin source prendrait l'emplacement de la classe comme une base. Il n'y a aucune référence à l'emplacement de la classe n'importe où dans la lecture du fichier de configuration. Ce n'est pas le cas. Je m'attendrais à ce qu'il fasse src / main / java , mais apparemment ce n'est pas ce que ça fait. J'ai essayé de mettre la ressource au même endroit que le fichier source, il n'a pas été trouvé là-bas non plus.


Ok, je pensais peut-être que cela a fallu source_path comme chemin d'accès au fichier source en cours de traitement.


J'ai trouvé Le doc pour Ceci qui mentionne "un nom de relatif est une séquence non nulle et non vide de segments de chemin séparés par '/'; '.' ' et '..' sont des segments de chemin non valides " pour expliquer pourquoi l'utilisation de .. ne fonctionne pas.


Je sais - je n'ai essayé que le chemin relatif comme solution de contournement. La question est de savoir pourquoi le contenu du dossier Ressources n'est-il pas sur le chemin source? Et pourquoi les fichiers sont-ils sur le chemin source, qui ne sont toujours pas trouvés?


Le chemin devrait être "/config.json" mais la ressource doit être sur la trajectoire de classe du processeur d'annotation. Donc, d'abord, les classes doivent être compilées (ressource sous le répertoire des classes cibles) et le processus de classe du processeur doit être correct, puis le traitement? Ces classes annotées ont-elles besoin de la configuration?


5 Réponses :


4
votes

J'ai regardé cela avec l'un des développeurs de projet Lombok. Si quelqu'un connaît le traitement de l'annotation, c'est eux;)

Notre conclusion était que le JavacFileManager qui gère la demande en interne, n'a pas de chemin d'accès à la résolution standardLocation.source_path à. Nous n'en sommes pas sûrs, mais cela pourrait être lié à la construction de grades.


0 commentaires

7
votes

Je m'attendrais à ce que les choses de src / main / ressources code> sont copiées sur cible / classes code> pendant la construction (avant le traitement de l'annotation). Dans ce cas, vous pouvez les ouvrir comme ceci:

ProcessingEnvironment pe = ...;
FileObject fileObject = pe.getFiler()
    .getResource( StandardLocation.CLASS_OUTPUT, "", "config.json" );
InputStream jsonStream = fileObject.openInputStream();


1 commentaires

La copie des ressources dans le dossier de classes de sortie ne semble pas se produire lors d'une construction de grades.



-2
votes
  • Si votre élément est une instance de typeElement , vous pouvez utiliser ce code pour trouver votre code source

    FileObject FileObject = Traitementenv.getFiler (). GetResource ( StandardLocation.source_path, élément.geclloseLement (). Tostring (), element.getsimplename () + ".java");

    1. ollement.geclloseLement () est votre package de classe, par exemple: com.fool
    2. élément.getsimplename () est votre nom de classe, par exemple: personne
    3. alors vous pouvez les imprimer: Chaluquantence Content = FileObject.getcharconsent (True);


0 commentaires

0
votes

J'ai eu le même problème et je cherchais une solution pendant un moment et j'ai trouvé Ce piratage cool qui fait l'affaire pour Android

et ci-dessous vous pouvez voir ma solution à partir du projet PURE Java / Kotlin P>

fun ProcessingEnvironment.getResourcesDirectory(): File {
val dummySourceFile = filer.createSourceFile("dummy" + System.currentTimeMillis())
var dummySourceFilePath = dummySourceFile.toUri().toString()

if (dummySourceFilePath.startsWith("file:")) {
    if (!dummySourceFilePath.startsWith("file://")) {
        dummySourceFilePath = "file://" + dummySourceFilePath.substring("file:".length)
    }
} else {
    dummySourceFilePath = "file://$dummySourceFilePath"
}

val cleanURI = URI(dummySourceFilePath)

val dummyFile = File(cleanURI)

val projectRoot = dummyFile.parentFile.parentFile.parentFile.parentFile.parentFile

return File(projectRoot.absolutePath + "/resources")
}


1 commentaires

L'utilisation de .parentfile.parentfile ... nécessite une profondeur d'emballage spécifique - et ne fonctionnera pas pour des projets utilisant un nombre différent de "". dans leurs noms de colis.



0
votes

La fonction suivante fonctionne pour moi avec un processeur d'annotation déclenchée par gradle, ce n'est pas les jolies une mais fonctionne: xxx

traitementenv est membre de Abstractprocessor


0 commentaires