barbitoff programmer`s blog

Здесь я публикую заметки из программерской жизни: грабли, на которые мне случилось наступить, проблемы, для которых было найдено элегантное (или не очень) решение, а также все, с чем мне пришлось столкнуться и чем хотелось бы поделиться =)
PS Если хотите меня поблагодарить - на странице есть 3 места, чтобы это сделать =)
Показаны сообщения с ярлыком JDK. Показать все сообщения
Показаны сообщения с ярлыком JDK. Показать все сообщения

вторник, 13 июня 2017 г.

Установка плагинов на старые версии Java VisualVM

Проблема

Есть некая старая версия Java VisualVM, к примеру, поставляемая с JDK 6 или JDK 7. При попытке установить на нее плагин через Tools -> Plugins (к примеру, Visual GC плагин для мониторинга GC) получаем ошибку скачивания некоторого файла с домена java.net.

Решение

Домен java.net закрыт, плагины для VisualVM теперь хостятся на visualvm.github.io. На странице https://visualvm.github.io/pluginscenters.html можно найти подходящий центр плагинов, который нужно прописать в Tools -> Plugins -> Settings вместо прописанного там центра.


пятница, 25 ноября 2016 г.

Бесследное удаление КриптоПРО JCP 2.x

Под Windows:
  • Сносим JDK
  • Удаляем из реестра HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Prefs\ru\/Crypto/Pro
Под Linux:
  • Сносим JDK
  • Удаляем /root/.java/
  • Удаляем /var/opt/cprocsp/
  • Если /usr/java/default не совпадает с только что снесенной JDK, то нужно удалить из нее .java/.systemPrefs/.ru (т.к. эта папка создается JCP почему-то именно в этой JDK, а не в той, куда ставится JCP)

четверг, 3 декабря 2015 г.

Spring Tools Suite: ошибка "You need to run build with JDK or have tools.jar on the classpath..." при просмотре pom-ки

Проблема

При открытии в Spring Tools Suite pom-ки проекта вверху отображается ошибка:
You need to run build with JDK or have tools.jar on the classpath...
Причина

STS запущен из-под java из jre, а не JDK.

Решение

Поправить PATH системы таким образом, чтобы java бралась из JDK, а не из JRE. 

вторник, 4 августа 2015 г.

JDK 1.6: баг при передаче unicode-символов с использованием Runtime.exec()

В JDK 6 имеется баг, поправленный только в 7ой версии, связанный с передачей unicode-символов при вызове Runtime.exec(). Например, т.н. "правые двойные кавычки" при таком вызове превращаются в обычные прямые двойные кавычки (хотя бывают и более неприятные кейсы, когда вызов вообще падает с Exception-ом).
Благо, для проблемы есть workaround, основанный на замене Runtime.exec() на использование ProcessBuilder. Ниже приведен пример вызова, взятый со stackoverflow:
String[] cmd = new String[]{"yourcmd.exe", "some argument with unicode characters"};      
Map<String, String> newEnv = new HashMap<String, String>();
newEnv.putAll(System.getenv());
String[] i18n = new String[cmd.length + 2];
i18n[0] = "cmd";
i18n[1] = "/C";
i18n[2] = cmd[0];
for (int counter = 1; counter < cmd.length; counter++)
{
    String envName = "JENV_" + counter;
    i18n[counter + 2] = "%" + envName + "%";
    newEnv.put(envName, cmd[counter]);
}
cmd = i18n;
ProcessBuilder pb = new ProcessBuilder(cmd);
Map<String, String> env = pb.environment();
env.putAll(newEnv);
final Process p = pb.start();

среда, 11 февраля 2015 г.

java.lang.UnsatisfiedLinkError: com.sun.glass.ui.win.WinApplication._submitForLaterInvocation

При запуске приложения, использующего JavaFX на достаточно старой JDK 1.7.0_09, получаю:
Exception in thread "Thread-2" java.lang.UnsatisfiedLinkError: com.sun.glass.ui.win.WinApplication._submitForLaterInvocation(Ljava/lang/Runnable;)V
        at com.sun.glass.ui.win.WinApplication._submitForLaterInvocation(NativeMethod)
        at com.sun.glass.ui.win.WinApplication.submitForLaterInvocation(WinApplication.java:215)
        at com.sun.glass.ui.InvokeLaterDispatcher.run(InvokeLaterDispatcher.java:101)
Лечится обновлением Java, в моем случае я обновился до 1.7.0_75. 

вторник, 19 ноября 2013 г.

Maven: Compilation failure без объяснения причин

Проблема

При запуске компиляции с помощью mvn валится ошибка "Compilation failure", которой не предшествует какой бы то ни было ругани javac-а, как это обычно бывает при некомпилируемом коде. При использовании ключа -e валится stacktrace, не сильно информативнее:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.
0:compile (default-compile) on project project-core: Compilation failure -> [Help
1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal o
rg.apache.maven.plugins:maven-compiler-plugin:3.0:compile (default-compile) on p
roject project-core: Compilation failure
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:213)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:153)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:145)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProje
ct(LifecycleModuleBuilder.java:84)
        ...
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.jav
a:230)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(La
uncher.java:409)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:
352)
Caused by: org.apache.maven.plugin.compiler.CompilationFailureException: Compila
tion failure
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute(Abstrac
tCompilerMojo.java:749)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute(CompilerMojo.ja
va:118)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(Default
BuildPluginManager.java:101)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor
.java:209)
        ... 19 more
[ERROR]
[ERROR]
[ERROR] For more information about the errors and possible solutions, please rea
d the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureExc
eption
[ERROR]
[ERROR] After correcting the problems, you can resume the build with the command
Причина

Пролить свет на причину ошибки помог анализ вывода запуска mvn с ключем -X, включающим вывод кучи отладочной информации. В частности, в выводе обнаружилась следующая строчка:
[DEBUG]   (f) executable = C:/Program Files (x86)/Java/jdk1.6.0_25/bin/javac.exe
Она привлекла внимание по той причине, что JAVA_HOME смотрит вовсе не туда, и вообще указанный путь не существует. Залез в settings.xml, и действительно, увидел там вот это:
<properties>
   <java.1.6.home>C:/Program Files (x86)/Java/jdk1.6.0_25</java.1.6.home>
   <java.1.6.compiler>${java.1.6.home}/bin/javac.exe</java.1.6.compiler>
</properties>
Исправление данного пути на корректный поправило компиляцию (впрочем, можно было бы и удалить этот блок вообще и понадеяться на переменные окружения).

понедельник, 28 октября 2013 г.

Java 7: Comparison method violates its general contract

После перехода с Java 6 на 7 одна из используемых приложением библиотек стала валиться с:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
Причина кроется в том, что в семерке переработана имплементация алгоритма сортировки, используемая в java.util.Arrays.sort и java.util.Collections.sort, и в случае некорректной реализации интерфейса Comparable она может генерировать данное исключение. Под некорректной понимается реализация, неконсистентная с реализацией equals() (например, если для некоторых эквивалентных объектов она возвращает значение, отличное от 0). Найти эту информацию можно в заметках о совместимости Java 7. 
Выход - переписать реализацию Comparable (в моем случае - не вариант, т.к. библиотека сторонняя и закрытая) либо воспользоваться системным свойством "java.util.Arrays.useLegacyMergeSort", позволяющим переключиться на старую имплементацию сортировки (сказать по правде, не пробовал, т.к. просто вернулся на JDK 6).
ЗЫ Спасибо http://www.yossale.com/?p=355.

четверг, 6 июня 2013 г.

jaxws-maven-plugin 2.2: ошибка Error executing: wsimport ... UndeclaredThrowableException: javax.xml.bind.annotation.XmlElementRef.required()

Проблема

При сборке проекта используется jaxws-maven-plugin версии 2.2 для генерации классов по wsdl. Собирается проект на JDK 6. При сборке падает:
Error executing: wsimport ... UndeclaredThrowableException: javax.xml.bind.annotation.XmlElementRef.required()
Под JDK 7 сборка проходит без проблем (ровно как и в связке jaxws-maven-plugin 2.1 + JDK 6). 

Решение

Не понял, чем именно вызвана проблема, но очевидно она связана с тем, что версия плагина - 2.2, тогда как JDK 6 идет с jax-ws / jaxb 2.1. Добавление jax-ws api 2.2 в endorsed при компиляции (как - я уже писал когда-то: http://barbitoff.blogspot.ru/2013/01/maven-wsimport-jdk-16.html) не помогает, что и логично - сборка валится при запуске wsimport, не доходя до компиляции. Проблема решается обновлением плагина jaxws-maven-plugin до версии 2.2.1.

четверг, 10 января 2013 г.

maven и jaxws-maven-plugin 2.2: проблема со сборкой на JDK 1.6.

Проблема:

Имеется проект, собираемый maven`ом с использованием jaxws-maven-plugin версии 2.2. Проект без проблем собирается с использованием JDK 1.7, однако при попытке собрать его на JDK 1.6 возникает ошибка:
Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default-compile) on project Fileadapter-ECM-WS: Compilation failure: Compilation failure:
symbol  : constructor Service(java.net.URL,javax.xml.namespace.QName,javax.xml.ws.WebServiceFeature[])
location: class javax.xml.ws.Service
Добавление в проект зависимости от jaxws-api 2.2:
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.2.8</version>
<scope>compile</scope>  
</dependency>

не помогает, т.к. при компиляции используется jaxws-api из JDK, а там, в случае JDK 1.6, находится версия jaxws-api 2.1.

Решение:

Уже когда-то писал про аналогичную проблему (http://barbitoff.blogspot.ru/2012/01/cannot-find-symbol-symbol-constructor.html), правда тогда собирал ant`ом, а не maven`ом. 
Решения, вобщем-то, два. Первое - перейти на jaxws-maven-plugin версии 2.1. Второе - использовать endorsed-механизм, чтобы заменить версию jaxws-api при сборке (если мы знаем, что в целевой среде, где будет выполняться приложение, будет jaxws-api версии 2.2 и реализующая его имплементация). Делается это следующим образом:
1) Во-первых, в проекте необходимо создать папку для endorsed-библиотек. Я создал её в корне проекта (на одном уровне с pom.xml) и называл "endorsed".
2) В созданную папку поместить jar-ник jaxws-api версии 2.2, скачать его можно тут.
3) Настроить maven-compiler-plugin на использование нашей endorsed-папки:
<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          <compilerArguments>
            <endorseddirs>${basedir}/endorsed</endorseddirs>
          </compilerArguments>
        </configuration>
      </plugin>
      <!-- ... -->
</build>
PS Конечно, правильнее с точки зрения философии maven будет не класть заранее jar-ник в папку endorsed, а размещать эту папку в директории сборки и копировать туда jar-ник как зависимость с помощью dependency-плагина уже при сборке.

среда, 17 октября 2012 г.

JAX-WS-клиент веб-сервиса: ошибка "com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class <xxx> is not found. Have you run APT to generate them?"

Проблема:

Веб-приложение, использующее JAX-WS-клиент к веб-сервису, отлично работало на машине разработчика, а при развертывании на Tomcat на промышленном сервере стало валиться с ошибкой:
com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class <xxx> is not found. Have you run APT to generate them?
Причина:

Вероятнее всего, старый JDK.

Решение:

Обновить JDK. Не знаю, до какой версии точно, но обновление до последнего JDK (1.6.0_26 в  репозитории Debian Lenny) в моем случае решило проблему. 

вторник, 17 июля 2012 г.

org.apache.commons.logging.LogConfigurationException: User-specified log class 'org.apache.commons.logging.impl.Log4JLogger' cannot be found or is not useable.

Часа полтора ушло на казалось бы простейшую проблему: использовать apache commons logging в связке с log4j. Проблема была в следующем: в веб-приложении, разворачиваемом на Tomcat 6, имеются файлы конфигурации commons-logging и log4j со следующим содержимым:

commons-logging.properties:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger
log4j.properties:
log4j.debug=false
log4j.rootLogger=DEBUG, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=%-4r [%t] %-5p %c %x - %m%n 
Первый конфигурационный файл должен подхватываться commons-logging`ом самостоятельно как первый с таким именем в CLASSPATH, путь ко второму указывается явно в web.xml. Сами jar-ники commons-logging-1.1.1.jar и log4j-1.2.15.jar в /WEB-INF/lib приложения лежат. Однако при попытке чтобы то ни было залогировать в веб-приложении валится исключение:
org.apache.commons.logging.LogConfigurationException: User-specified log class 'org.apache.commons.logging.impl.Log4JLogger' cannot be found or is not useable.
Как оказалось, проблема была в следующем: commons-logging-1.1.1.jar лежал также и в %JAVA_HOME%/jre/lib/ext (так уж получилось, что он залетел туда при установке КриптоПРО JCP). Поэтому и загружался этот jar-ник не тем класслоадером, что и остальные либы веб-приложения, и jar-ника log4j в /WEB-INF/lib ему было не видно. Выход - либо закинуть jar-ник log4j туда же в %JAVA_HOME%/jre/lib/ext, либо - удалить оттуда commons-logging-1.1.1.jar (в моем случае - не вариант, т.к. нарушило бы работу JCP).

четверг, 5 апреля 2012 г.

Настройка пути к JDK, который используется Netbeans`ом

В Windows путь к JDK задается в файле etc/netbeans.conf относительно директории установки NetBeans в переменной netbeans_jdkhome:
# Default location of JDK, can be overridden by using --jdkhome <dir>:
netbeans_jdkhome="C:\jdk"

понедельник, 12 марта 2012 г.

Установка Sun (Oracle) JDK в Ubuntu 11.10

В репозиториях убунты есть только OpenJDK, поэтому необходимо скачать JDK с сайта Oracle и установить его самостоятельно:
1) Качаем самораспаковывающийся архив с JDK: http://www.oracle.com/technetwork/java/javase/downloads/index.html (выбираем вариант вида "jdk-6u31-linux-i586.bin")
2) Распаковываем куда-нибудь. Для этого:
chmod +x jdk-6u31-linux-i586.bin
./jdk-6u31-linux-i586.bin 
Появится папка jdk1.6.0_31.
3) Копируем jdk1.6.0_31 в /usr/lib/jvm:
sudo cp ./jdk1.6.0_31 /usr/lib/jvm -r
После этого, скажем, Netbeans, при установке уже увидит новую JDK. 
4) Устанавливаем новую Java как Java по-умолчанию:
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.6.0_31/bin/java" 1
sudo update-alternatives --set java /usr/lib/jvm/jdk1.6.0_31/bin/java
5) Неплохо бы ещё установить переменные окружения JAVA_HOME, JRE_HOME и CLASSPATH. Для этого нужно создать исполняемый файл в директории /etc/profile.d (например, с названием java_env.sh) и добавить в него следующие строчки:
JAVA_HOME=/usr/lib/jvm/jdk1.6.0_31
JRE_HOME=/usr/java/jdk1.6.0_31/jre
CLASSPATH=$JAVA_HOME/lib:.
export JAVA_HOME JRE_HOME CLASSPATH
Есть и другие варианты, но такой универсален в том плане, что отразится на всех пользователях, и, при этом, переменные окружения не слетят при возможном обновлении файла /etc/profile при обновлении системы.

среда, 7 марта 2012 г.

Проблема при компиляции проекта, использующего com.sun.xml.internal.ws.*

Проблема:

В проекте используются следующие импорты:
import com.sun.xml.internal.ws.client.BindingProviderProperties;
import com.sun.xml.internal.ws.developer.JAXWSProperties;
При запуске из NetBeans на Tomcat всё проходит нормально, однако при попытке сделать "Clean & Build" вываливается:

package com.sun.xml.internal.ws.client does not exist
import com.sun.xml.internal.ws.client.BindingProviderProperties;
package com.sun.xml.internal.ws.developer does not exist
import com.sun.xml.internal.ws.developer.JAXWSProperties;
Подключение к проекту rt.jar из jre не решает проблему.

Решение:

Сначала думал, что проблема в Netbeans, оказалось - нет, в JDK (http://netbeans.org/bugzilla/show_bug.cgi?id=199780). Решается проблема установкой опции "-XDignore.symbol.file=true" при компиляции проекта. Для  maven это делается так:

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <verbose>true</verbose>
          <compilerArgs>
            <arg>-XDignore.symbol.file=true</arg>
          </compilerArgs>
        </configuration>
      </plugin>