Есть ли какой-нибудь способ найти классы с неправильным именем пакета в Netbeans?

#java #netbeans #compiler-errors #package

#java #netbeans #ошибки компилятора #пакет

Вопрос:

После многих лет разработки Java я был потрясен, узнав, что компилятор не проверяет, действительно ли имя пакета соответствует пути к исходному файлу Java.

Вы можете написать это:

 package abcd; 
class Xyz {
}
  

и это будет скомпилировано, даже если Xyz.java находится в папке efgh. Я получаю предупреждение при редактировании файла в Netbeans, но не более того. Фактически, это привело к ошибке, которую было очень трудно обнаружить: http://netbeans.org/bugzilla/show_bug.cgi?id=197320

В любом случае есть какой-нибудь способ получать предупреждения или ошибки?

Комментарии:

1. Используйте Eclipse. Это выдаст ошибку, если пакет неправильный.

2. Я полагаю, javac допускает это, потому что у вас есть опция -d, которая теоретически могла бы это исправить.

3. javac -d этого не решит. Я не хочу, чтобы javac решал эту проблему, я просто хочу, чтобы он сообщал об этом.

Ответ №1:

С помощью gnu-find вы можете выполнять поиск по всему проекту. cd в корневой каталог исходного кода проекта, а затем:

 find PROJECT -type f -name "*.java" -exec ./pmatchd.sh {} ";"
  

Вам нужен pmatchd.sh — скрипт:

 #!/bin/bash
#
dir=$(dirname $1)
d=${dir////.}
headline=$(head -n1 $1) 
p=${headline#package }
if [[ $d";" != $p ]]
then 
    echo "mismatch: "   $d " "   $p   " "   $1
fi
  

Если вам это нравится, вы переместите его в местоположение в path, а не в $ PWD.

Комментарии:

1. хорошая идея, и я могу сделать это частью нашего процесса непрерывной интеграции… Я проверю это и вернусь как можно скорее 🙂

2. однако я бы предпочел использовать что-то, что является частью экосистемы java, если это возможно

3. Я понимаю это, но для меня это слишком большая работа. Однако возможны некоторые улучшения: скрипты должны работать без cd доступа к каталогу. И, возможно, оператор ‘package’ не всегда находится в первой строке. Я думаю, в scala вы могли бы сделать это в 30 строках, в Java — в 100 строках. 🙂

4. на самом деле, я искал какой-нибудь переключатель компилятора или какой-нибудь инструмент, входящий в состав дистрибутива. Кажется, его не существует.

Ответ №2:

Это не ошибка; это неудобство. Вы могли бы поместить каждый файл .java в один каталог, причем каждый класс находился бы в другом пакете, и при этом все равно правильно скомпилировать и получить структуру вывода, соответствующую тому, какими были пакеты классов.

Комментарии:

1. Ваше утверждение верно, но я хотел бы знать, как сообщить о неудобствах, если это возможно, во время компиляции.

Ответ №3:

Имя пакета — это не что иное, как пространство имен. Его можно преобразовать в путь к файлу, и большинство загрузчиков классов ожидают найти скомпилированный файл класса в расположении, подобном

 <classpath-entry>/packagename.replace(".","/")/classname.class
  

(Но это дело загрузчика классов)

Ответ №4:

Eclipse не допустит этого и покажет это как ошибку компиляции. Если Netbeans просто показывает это как предупреждение, вы могли бы изменить его, чтобы оно отображалось как ошибка в настройках компиляции.

Комментарии:

1. Netbeans использует javac, поэтому вопрос относится к нему.