Comments 68
как баги в maven (по большей части видел в плагинах, типа MJAR-249).
Ну т.е., не у вас одного сломалось, разработчики maven тоже вынуждены были фиксить кое-что. И это нехороший признак — никогда на моей памяти новая версия JDK не ломала системы сборки.
А вы чем собираете? У меня с Maven проблем не было, всё собирается, я даже ни каких module-info.java не добавлял. И в зависимостях куча древних JAR-ов. И в проекте ничего не менял, всё стандартно по мавенскому шаблону.
>Это обычно нужно, чтобы понять, где искать файлы приложения — конфигурацию, плагины и т.п.
У приложения должен быть константный каталог в user.home с нужной конфигурацией. Если хотите узнать о текущем процессе больше, то появился новый API ProcessHandle.
>Files.readAllLines("/etc/mime.types", Charset.defaultCharset())
Проверил — у меня работает.
>Ничего просто не соберётся
Это про модульные приложения. Обычные на JAR'ах и CLASSPATH'ах соберутся. Точнее, соберутся не хуже чем в 9 (там тоже понаполомали).
У приложения должен быть константный каталог в user.home с нужной конфигурацией.
Угу, а статические конфиги всякие, плагины, ресурсы и прочую муть? А если у меня «portable» (а у меня именно так)?
В папке приложения теперь может быть только один файл? Простите, но это глупо. А ProcessHandle вернёт вам совершенно не то — файл может быть запущен разными способами, включая запуск из всяких «запускальщиков».
>Files.readAllLines("/etc/mime.types", Charset.defaultCharset())
Проверил — у меня работает.
Проверили эту строчку или «Files.readAllLines(»/etc/mime.types", Charset.defaultCharset())"? Падает в недрах JRE.
/etc/app.name
>плагины
Обычно в user.home/app.name, можно в /usr/lib/app.name Можно даже в /usr/lib/jvm
>ресурсы и прочую муть
Обычно пакуется в JAR
>файл может быть запущен разными способами, включая запуск из всяких «запускальщиков»
Если вам нужны подобные хаки, то гуглите новые хаки для 10-ки, если старые перестали работать.
>Проверили эту строчку или
Не нашел, чем у вас там строчка отличается. Просто скопировал, код из статьи в IDE и всё.
Один JAR — снова, вы вводите искусственные ограничения.
Простой пример — приложение под Windows взаимодействует с другими исполняемыми файлами, которые оно же устанавливает. Или приложение сильно модульное, где набор модулей задаётся на этапе установки. И ещё 1001 и одна ситуация.
Если вам нужны подобные хаки, то гуглите новые хаки для 10-ки, если старые перестали работать.
Хаки? Мне нужно обычное кросс-платформенное desktop GUI приложение и чтобы оно реально работало. Хаки… Тут ещё для девятки половину «хаков» не написали, а они снова поломали.
Да. В Windows приложение должно лежать в Program Files/app.name. И по прежнему есть user.home
>Но фактически вы предлагаете в папке программы держать ровно один файл.
Нет, можете там держать остальные библиотеки требуемые для старта приложения. В 9-ке появилась возможность делать сборки, поэтому будут еще файлы JRE. Но я пока такую сборку не пробовал.
>приложение под Windows взаимодействует с другими исполняемыми файлами
>Или приложение сильно модульное, где набор модулей задаётся на этапе установки
Для таких ситуаций делают инсталятор. И как я говорил, всё должно лежать в Program Files/app.name, в других ОС читайте инструкции, где и что должно лежать.
>Хаки? Мне нужно обычное кросс-платформенное desktop GUI приложение и чтобы оно реально работало.
Я вам предложил вариант. Он рабочий. Можете также использовать ProcessHandle API, если вы не наврнёте новых хаков на пускалку вашего JAR-а, то это API будет нормально работать.
stackoverflow.com/a/3923182/8238588
см. метод getResourcesFromJarFile
Я не могу сказать почему отломился readAllLines в моём случае. Там происходит какая-то хрень с буферами внутри и всё разлетается. И дело не в кодировке, так как файл /etc/mime.types содержит только ASCII. Просто сам факт того, что JVM v10 подавился вполне нормальным текстовым файлом, который нормально читался в 8-й JVM и кучей других программ — говорит сам за себя.
И что, вы в рантайме не можете создать user.home/.app.name скопировав туда конфиги из JAR-а? И туда же устанавливать плагины, если у вас настолько простое развёртывание?
>говорит сам за себя
В 99.9% подобных багов это криворукость разработчика, а не сбой промышленной платформы с миллионами разработчиков.
Промышленная платформа, как только мы говорим о десктоп приложениях — говно с огромными проблемами. Имею наглость так утверждать. Кроссплатформенности нет. Совместимость между версиями рушится раз в год. Базового функционала нет. Критические баги висят по пять лет.
Установщик или ваше приложение в рантайме.
>А если два приложения на одном компьютере?
Продумываете где и что хранить, когда два приложения на компьютере.
>Кроссплатформенности нет.
Есть, но в разумных пределах.
>говно с огромными проблемами. Имею наглость так утверждать.
Вас никто не держит. Только на других платформах всё еще хуже.
Можно, конечно, но это был немного не тот случай. Просто немного печально, что больше нельзя получить путь к файлу с entry point. Требуется переписывание из-за нарушения обратной совместимости, как минимум.
pastebin.com/6QHQH75H
Нет, здесь он начинает расцвет.
>и тогда на смену Java нужно искать другой инструмент
Т.е. искать новый инструмент и переписывать код с нуля у вас время найдётся, а почитать документацию и пофиксить
И я, например, отлично понимаю, когда у человека нет времени в игрушки играться. У него есть задача ему нужен инструмент, а если инструмент не работает и всё время ломается, то его нужно менять инструмент. Когда время позволяет — я копаюсь в говне. Но если у меня есть работающее, свеже-написанное приложение, а мне звонит заказчик и в панике говорит, что юзеры не могут больше скачать JRE9, то времени и желания переписывать кучу кода у меня нет — мне нужно часто и много кушать.
Так сидите на 8-ке, она до 2020 поддерживается. Зачем вы ринулись под 9-ку всё переписывать? На 9-ку толком никто не переходил, только с 10-ой, когда более-менее всё отшлифовалось — люди стали переползать.
>а если инструмент не работает и всё время ломается, то его нужно менять инструмент
А вы думаете где-то лучше? ) Везде так, это ИТ, куча легаси и постоянное движение впёред. И джава среди прочих инструментов еще более-менее вменяемая.
Всё верно, зачем новую разработку начинать на устаревшей платформе? Кто так делает?
>все время предлагает перейти на более свежую версию
Не видел такого, т.е. у пользователя на Windows стоит 8-ка и Updater постоянно предлагает обновиться на 10-ку?
>Это как бы признак огромного кризиса и проблем в языке.
Нет, это перемены, необходимые для дальнейшего роста популярности JVM. Сделали, то, что давно нужно было сделать. Такие точки перелома есть везде, например Windows 98 -> Windows XP или x32 -> x64 и т.д.
Про malformed input у меня было в восьмёрке ещё. Это несовпадение кодировками. У меня было когда читал в utf8 (стандартная кодировка), а в файле был иврит в какой-то ещё (iso что-то, windows что-то — не помню).
Можете создать свой FileTypeDetector через ServiceLoader он подгрузится и выполнится первым. То что в файле ASCII это без разницы. Там нет детектора кодировки файла, поэтому берётся Charset.defaultCharset(), вы сами это указали в статье. И видимо у вас там какой-нибудь UTF-16 возвращается и он начинает читать однобайтовую кодировку, как двухбайтовую.
String csn = GetPropertyAction
.privilegedGetProperty("file.encoding");
Charset cs = lookup(csn);
if (cs != null)
defaultCharset = cs;
else
defaultCharset = sun.nio.cs.UTF_8.INSTANCE;
В конечном итоге всё равно проверяется по расширению. Поэтому проще было не дёргать probeContentType а проверять расширение самому. Но использование кастомного FileTypeDetector — это слишком
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.charset.Charset;
public final class Test {
public final static void main(final String args[])
throws Exception {
Files.readAllLines(Paths.get("/etc/mime.types"), Charset.defaultCharset());
}
}
Стэктрэйс:
$ java Test
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at java.nio.file.Files.readAllLines(Files.java:3205)
at Test.main(Test.java:8)
[kurila@ruxxkurilad2c tmp]$ java -version
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
openjdk version "1.8.0_162"
OpenJDK Runtime Environment (build 1.8.0_162-b12)
OpenJDK 64-Bit Server VM (build 25.162-b12, mixed mode)
if (cr.isUnderflow()) {
if (endOfInput && in.hasRemaining()) {
cr = CoderResult.malformedForLength(in.remaining());
// Fall through to malformed-input case
} else {
return cr;
}
}
final var someStrings = (List<String>) new ArrayList<>();
да уж. за что боролись. както совсем подурацки выглядит.
хотя конечно можно понять причины.
но хотелось тыгда уж чтото вроде
List<String> someStrings = new ArrayList<>();
List<> someStrings = new ArrayList<String>();
возможно даже лучше. хотя смотря какая цель.
конкретно для локальной переменной — ежели её передавать куда то, то нужно будет скобки писать и т.д., если она не List ну и в таком духе
При вызове любой метод, принимающий List, пример и его наследника.
Ну… не совсем любой.
Вот вам пятничный пример:
import java.util.List;
import java.util.ArrayList;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class Test {
public static void main(String... args) throws Throwable {
ArrayList<String> list = new ArrayList<>();
list.add("Test!");
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle testMH = lookup.findStatic(
Test.class, "test",
MethodType.methodType(void.class, List.class)
);
testMH.invokeExact((List<String>) list);
System.out.println();
testMH.invokeExact(list);
}
private static void test(List<String> values) {
for(String s : values) {
System.out.println(s);
}
}
}
Сколько раз будет напечатана строка "Test!" после компиляции и запуска?
а джава как должна узнать какой супер интерфейс из множества делать var'у?
ну и вам очевидно «подсвечивает» не джава а IDE, так что решение этой проблемы на их плечах и в чём тут «джаву» обвинять я не понимаю.
Ну и в целом какие-то глобальные выводы делаете от обиды, что само сразу работать не стало :)
ЗЫ: «Провал при попытке определения MIME-типа файла.» это тоже мега проблемой не выглядит и на мой взгляд джуну по силу разобраться в чём дело.
а джава как должна узнать какой супер интерфейс из множества делать var'у?
а почему нет? минимально возможный, на основе статического анализа кода. не?
ну и вам очевидно «подсвечивает» не джава а IDE, так что решение этой проблемы на их плечах и в чём тут «джаву» обвинять я не понимаю.
ну если IDE догадывается, то и компилятор тоже вполне мог бы
Ну и в целом какие-то глобальные выводы делаете от обиды, что само сразу работать не стало :)Не совсем. Я ждал что в 10-ке проблем с модулями уже не будет, но осталось множество вещей, которые делают модули совершенно неюзабельными. Не стало работать ни сразу, ни потом. Для полноты картины — вот, например, удачная цитата:
Wow… this makes jlink from hard to use to useless for the foreseeable future. – pupeno Apr 7 at 9:36
взято отсюда
stackoverflow.com/questions/48408454/java-9-generating-a-runtime-image-with-jlink-using-3rd-party-jars
ЗЫ: «Провал при попытке определения MIME-типа файла.» это тоже мега проблемой не выглядит и на мой взгляд джуну по силу разобраться в чём дело.У меня нету столько джунов, чтобы бросить их на решение этих 1000 и 1 мелочей. Самому — лень, естественно. Не барское это дело. Я как-то, когда берусь за задачу, обычно выставляю себе лимит времени.
минимально возможныйКак определен «минимальный»?
ну если IDE догадывается, то и компилятор тоже вполне мог быЗачем вообще в типе подменять на интерфейс?
Я предлагаю вам задуматься над этим «так принято» и переосмыслить критически. Посмотреть в каких случаях что куда приводит, в том числе с учетом вариативности, в том числе с учетом лямбд.
Пока что выглядит как призыв к анемичности (если я корректно интерпретировал «минимальность»).
Зависит от конкретной ситуации
var strings = new ArrayList<String>();
Какой здесь должен быть тип у переменной strings?
Object, если это конец области видимости. Если нет, то вы не раскрыли тему
Более того, если тип определяется дальнейшим использованием то эта ситуация полностью идентична как раз typeOf(strings) ≡ ArrayList<String>.
В джаве тип определяется декларацией, а не использованием.
- В таком случае весь смысл "var" просто отваливается.
И var иначе работать не имеет права.
- Непонятно, на основании чего сделан такой вывод. Законы мироздания мешают? В некоторых JVM-based языках вывод типа вполне работает. Что мешало сделать его в яве — непонятно.
Соответственно, данная строчка должна определять тип однозначно и независимо
- Кому должна?
Если хочешь специфику, пиши конкретный тип.
Так вот.
Hello-world проект на Spring Boot скачан со спрингового же репозитория с Java 9 не работает.
На 8-й всё шикарно. =)
Чую скоро будет боль. Много боли.
Что уж говорить, если даже стандартный пример Java2Demo, скачанный с официального сайта Oracle из раздела JDK 8u172 Demos and Samples, просто не запускается на JDK 10.
Они все испортят ©! Сейчас мы переживаем фактически начало заката Java. Экосистема не будет поспевать за новым релизным циклом, а Java движется в сторону постоянного ломания совместимости. С Java 8 прокатило, поскольку все давно ждали лямбды и стримы. Но в последних версиях количество вещей реально полезных для финального пользователя, остается минимальным. В итоге экосистема форкнется на две: с одной стороны будет небольшая группа early adopters, а с другой — огромный "легаси", который не будет спешить никуда мигрировать. Резко упадет количество решений, совместимых с новыми версиями Java, и общий интерес к Java платформе потихоньку начнет падать в угоду альтернативам. По моим оценкам Java 8 задержится еще минимум лет на 5, а потом внезапно появится что-то еще...
С трудом и болью перенес один из проектов на 9, на 10 не смог — отваливаются библиотеки. А теперь 9 не поддерживается, на 8 обратно переходить — как-то тупо. Так и сижу на 9.
Записки о миграции на Java 10