簡體   English   中英

如何抑制特定目錄或文件(例如生成的代碼)的 Java 警告

[英]How to suppress Java warnings for specific directories or files such as generated code

我正在使用一個解析器生成器,它創建了一些難看的代碼。 結果,我的 Eclipse 項目有幾十個來自生成的源文件的警告。 我知道我可以使用@SuppressWarning注釋來抑制特定元素中的特定警告,但是當解析器生成器再次運行時,我手動添加的任何注釋都將丟失。 有沒有辦法配置 Eclipse 以抑制特定文件或目錄的警告?

從版本 3.8 M6 開始,Eclipse(確切地說:JDT)為此具有內置功能。 它可以通過項目的構建路徑進行配置:項目屬性 > Java 構建路徑 > 編譯器 > 源

在此處輸入圖片說明

在此宣布: Eclipse 3.8 和 4.2 M6 - 新的和值得注意的,稱為Selectively ignore errors/warnings from source folders 這也是截圖的來源。 這是在之前鏈接的Bug 220928上開發的新功能。

對此有一張票, Bug 220928 ,此后已為 Eclipse 3.8 完成。 有關詳細信息,請參閱此答案

如果您堅持使用 Eclipse 3.7 或更低版本:用戶“Marc”對該票的評論在評論 35 中創建了(或至少鏈接到)一個名為“warningcleaner”的插件。 在等待將此功能集成到 Eclipse 中時,我使用它取得了很大的成功。

這真的很簡單:

  1. 安裝插件。
  2. 右鍵單擊項目並選擇“添加/刪除生成的代碼性質”。
  3. 打開項目設置(右鍵單擊並選擇“屬性”)。
  4. 打開“警告清潔器”選項卡。
  5. 選擇要忽略警告的源文件夾。

警告清潔器屏幕截圖

我通過使用 maven regexp 替換插件解決了這個問題 - 它沒有解決原因,但治愈了痛苦:

<plugin>
  <groupId>com.google.code.maven-replacer-plugin</groupId>
  <artifactId>maven-replacer-plugin</artifactId>
  <version>1.3.2</version>
  <executions>
<execution>
  <phase>prepare-package</phase>
  <goals>
    <goal>replace</goal>
  </goals>
</execution>
  </executions>
  <configuration>
<includes>
  <include>target/generated-sources/antlr/**/*.java</include>
</includes>

<regex>true</regex>
<regexFlags>
  <regexFlag>MULTILINE</regexFlag>
</regexFlags>

<replacements>
  <replacement>
    <token>^public class</token>
    <value>@SuppressWarnings("all") public class</value>
  </replacement>
</replacements>
  </configuration>
</plugin>

請注意,我沒有設法使 ** 符號起作用,因此您可能必須准確指定路徑。

有關如何不生成重復 @SupressWarnings 的改進,請參閱下面的評論

我認為您能做的最好的事情就是啟用項目特定設置以顯示警告。

窗口 -> 首選項 -> Java -> 編譯器 -> 錯誤/警告

表單頂部是用於配置項目特定設置的鏈接。

用戶@Jorn 暗示 Ant 代碼可以做到這一點。 這是我所擁有的

<echo>Adding @SuppressWarnings("all") to ANTLR generated parser/lexer *.java</echo>
<echo> in ${project.build.directory}/generated-sources/antlr/</echo>
<replace dir="${project.build.directory}/generated-sources/antlr/" 
         summary="true" 
         includes="**/*.java" 
         token="public class" 
         value='@SuppressWarnings("all") public class' />

請注意,Ant 的 <replace> 執行文本替換,而不是正則表達式替換,因此它不能像 maven regexp 替換插件那樣使用標記中的 ^ 元字符來匹配行的開頭。

我在我的 Maven pom 中從 maven-antrun-plugin 運行 Antlr 的同時這樣做,因為 ANTLR maven 插件不能很好地與 Cobertura maven 插件配合使用。

(我意識到這不是原始問題的答案,但我無法在評論/回復另一個答案中格式化 Ant 代碼,只能在答案中)

我不認為 Eclipse 本身就提供了一種在目錄級別執行此操作的方法(但我不確定)。

您可以將生成的文件放入單獨的 Java 項目,並控制該特定項目的警告。

無論如何,我通常更喜歡將自動生成的代碼放在單獨的項目中。

您只能在項目級別取消警告。 但是,您可以配置問題選項卡以抑制來自文件或包的警告。 進入配置內容菜單並使用“工作集:”范圍。

這個小的 python 腳本“修補”了 M2E 生成的.classpath文件,並將所需的 XML 標記添加到所有以target/generated-sources開頭的源文件夾中。 您可以從項目的根文件夾中運行它。 顯然,當從 M2E 重新生成 Eclipse 項目信息時,您需要重新運行它。 顯然,風險自負;-)

#!/usr/bin/env python
from xml.dom.minidom import parse
import glob
import os

print('Reading .classpath files...')
for root, dirs, files in os.walk('.'):
    for name in files:
        if (name == '.classpath'):
            classpathFile = os.path.join(root, name)
            print('Patching file:' + classpathFile)
            classpathDOM = parse(classpathFile)
            classPathEntries = classpathDOM.getElementsByTagName('classpathentry')
            for classPathEntry in classPathEntries:
                if classPathEntry.attributes["path"].value.startswith('target/generated-sources'):
                    # ensure that the <attributes> tag exists
                    attributesNode = None;
                    for attributes in classPathEntry.childNodes:
                            if (attributes.nodeName == 'attributes'):
                                attributesNode = attributes

                    if (attributesNode == None):
                        attributesNode = classpathDOM.createElement('attributes')
                        classPathEntry.appendChild(attributesNode)

                    # search if the 'ignore_optional_problems' entry exists
                    hasBeenSet = 0
                    for node in attributesNode.childNodes:
                        if (node.nodeName == 'attribute' and node.getAttribute('name') == 'ignore_optional_problems'):
                            # it exists, make sure its value is true
                            node.setAttribute('value','true')
                            #print(node.getAttribute('name'))
                            hasBeenSet = 1

                    if (not(hasBeenSet)):
                        # it does not exist, add it
                        x = classpathDOM.createElement("attribute")
                        x.setAttribute('name','ignore_optional_problems')
                        x.setAttribute('value','true')
                        attributesNode.appendChild(x)

            try:
                f = open(classpathFile, "w") 
                classpathDOM.writexml(f)
                print('Writing file:' + classpathFile)
            finally:
                f.close()
print('Done.')

我正在對一些使用 Ant 生成 Java 解析器的 ANTLR 語法執行此操作。 Ant構建腳本添加@SuppressWarnings("all")以一個.java文件, @Override到另一個幾個方法。 如果你有興趣,我可以看看它是如何完成的。

自從我發布警告清除插件已經有一段時間了,現在我使用的是 Eclipse 3.8,我不再需要它了。 然而,對於那些仍然需要這個插件的人,我已經在 github 上發布了它,更新站點在 bintray 上。 如果您仍在使用 Eclipse 3.7 或更早版本,這可能很有用。 檢查此站點以獲取安裝詳細信息。

在 ANTLR 2 的情況下,可以通過在語法文件中的類聲明之前添加@SuppressWarnings來抑制生成代碼中的警告,例如

{@SuppressWarnings("all")} class MyBaseParser extends Parser;

如果 eclipse 項目是使用Eclipse 插件的eclipse命令從 gradle 生成的,則可以通過在build.gradle文件的頂層添加以下內容來設置Selectively ignore errors/warnings from source folders選項:

eclipse.classpath.file {
    whenMerged { classpath ->
        classpath.entries.each { entry -> 
            if (entry.path.contains('build/generated/parser')) {
                entry.entryAttributes['ignore_optional_problems'] = true
            }
        }
    }
}

這假設生成的源位於build/generated/parser文件夾中。

這可以通過從構建路徑中排除某些目錄來完成(以下示例使用 Eclipse 3.5 給出)

[1] 調出Java Build Path

  • 單擊 Package Explorer 中的項目
  • 右鍵,屬性
  • 選擇 Java 構建路徑

[2] 添加要排除的目錄

  • 源選項卡應包含項目源文件夾的詳細信息
  • 展開源文件夾並找到“排除:”屬性
  • 選擇“排除:”並單擊“編輯”
  • 使用添加/添加多個選項將文件夾添加到排除模式中
  • 單擊完成,然后確定 Eclipse 重建。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM