Меню Рубрики

Установка java portable для

Делаем Java приложение независимым от установки JRE или переносным (portable)

Одна из основных трудностей распространения Java программ – необходимость наличия на компьютере пользователя среды выполнения Java Runtime Environment (JRE). Именно поэтому переносные (portable) приложения на Java редкость.

В тоже время эту проблему вполне можно разрешить и создать не только переносное, но и «обычное» приложение, которое не будет требовать наличия предустановленной JRE.

Однако, учитывая кроссплатформенность Java, сразу отметим, что в данной статье речь пойдёт о решении данной задачи применительно к среде Windows.

Существует два основных подхода к решению данной задачи.

Способ 1. Преобразование в нативный код

Иначе говоря, преобразование из jar в exe.

Казалось бы, это самый очевидный способ. Но, на самом деле, он самый трудно реализуемый и практически не работоспособный.

Сконвертировать jar в exe в принципе не проблема. В частности, есть масса утилит, которые позволяют это сделать. Однако подавляющее практически все они не избавляют от необходимости устанавливать JRE. Без JRE exe файл, созданный этими утилитами, всё равно не запустится.

Те же из них, что, если верить описанию, претендуют на полное решение данной проблемы, давно не развиваются и перед применением их необходимо самих компилировать из исходных кодов.

Способ 2. Использование переносной версии JRE

Этот способ основан на том, что JRE может работать и без установки на компьютер. Достаточно скачать архив с официальной страницы загрузки (ссылка в конце статьи) и распаковать его в любую папку. После этого JRE уже готов к работе.

Однако запустить Java программу в этом случае можно только двумя способами:

  • Из командной строки;
  • С помощью программы загрузчика.

Первый вариант не подходит, так как слишком сложен для рядового пользователя. Остаётся второй.

Принцип работы загрузчика, на самом деле, достаточно прост. Программа передаёт JRE команды необходимые для запуска Java приложения и после этого закрывается. Тем самым автоматизируя процесс запуска, выполняемый в случае командной строки вручную.

Рассмотрим пример написания такого загрузчика на Delphi. Предположим, что загрузчик, jar файл с Java приложением и папка с JRE расположены в одной общей папке.

Определим константы (относительный путь к исполняемому файлу JRE и передаваемые команды (включают относительный путь к файлу Java приложения)).

источник

Инструменты для запуска и разработки Java приложений, компиляция, выполнение на JVM

Ни для кого не секрет, что на данный момент Java — один из самых популярных языков программирования в мире. Дата официального выпуска Java — 23 мая 1995 года.

Эта статья посвящена основам основ: в ней изложены базовые особенности языка, которые придутся кстати начинающим “джавистам”, а опытные Java-разработчики смогут освежить свои знания.

* Статья подготовлена на основе доклада Евгения Фраймана — Java разработчика компании IntexSoft.
В статье присутствуют ссылки на внешние материалы
.

1. JDK, JRE, JVM

Java Development Kit — комплект разработчика приложений на языке Java. Он включает в себя Java Development Tools и среду выполнения Java — JRE (Java Runtime Environment).

Java development tools включают в себя около 40 различных тулов: javac (компилятор), java (лаунчер для приложений), javap (java class file disassembler), jdb (java debugger) и др.

Среда выполнения JRE — это пакет всего необходимого для запуска скомпилированной Java-программы. Включает в себя виртуальную машину JVM и библиотеку классов Java — Java Class Library.

JVM — это программа, предназначенная для выполнения байт-кода. Первое преимущество JVM — это принцип “Write once, run anywhere”. Он означает, что приложение, написанное на Java, будет работать одинаково на всех платформах. Это является большим преимуществом JVM и самой Java.

До появления Java, многие компьютерные программы были написаны под определенные компьютерные системы, а предпочтение отдавалось ручному управлению памятью, как более эффективному и предсказуемому. Со второй половины 1990-х годов, после появления Java, автоматическое управление памятью стало общей практикой.

Существует множество реализаций JVM, как коммерческих, так и с открытым кодом. Одна из целей создания новых JVM — увеличение производительности для конкретной платформы. Каждая JVM пишется под платформу отдельно, при этом есть возможность написать ее так, чтобы она работала быстрее на конкретной платформе. Самая распространённая реализация JVM — это JVM Hotspot от OpenJDK. Также есть реализации IBM J9, Excelsior JET.

2. Выполнение кода на JVM

Согласно спецификации Java SE, для того, чтобы получить код, работающий в JVM, необходимо выполнить 3 этапа:

  • Загрузка байт-кода и создание экземпляра класса Class
    Грубо говоря, чтобы попасть на JVM, класс должен быть загружен. Для этого существуют отдельные класс-загрузчики, к ним мы вернемся чуть позже.
  • Связывание или линковка
    После загрузки класса начинается процесс линковки, на котором байт-код разбирается и проверяется. Процесс линковки в свою очередь происходит в 3 шага:

— verification или проверка байт-кода: проверяется корректность инструкций, возможность переполнения стека на данном участке кода, совместимость типов переменных; проверка происходит один раз для каждого класса;
— preparation или подготовка: на данном этапе в соответствии со спецификацией выделяется память под статические поля и происходит их инициализация;
— resolution или разрешение: разрешение символьных ссылок (когда в байт-коде мы открываем файлы с расширением .class, мы видим числовые значения вместо символьных ссылок).

  • Инициализация полученного объекта Class
    На последнем этапе класс, который мы создали, инициализируется, и JVM может начинать его исполнение.
  • 3. Загрузчики классов и их иерархия

    Вернемся к загрузчикам классов — это специальные классы, которые являются частью JVM. Они загружают классы в память и делают их доступными для выполнения. Загрузчики работают со всеми классами: и с нашими, и с теми, которые непосредственно нужны для Java.

    Представьте ситуацию: мы написали свое приложение, и помимо стандартных классов там есть наши классы, и их очень много. Как с этим будет работать JVM? В Java реализована отложенная загрузка классов, иными словами lazy loading. Это значит, что загрузка классов не будет выполняться до тех пор, пока в приложении не встретится обращение к классу.

    Иерархия загрузчиков классов

    Первый загрузчик классов — это Bootstrap classloader. Он написан на C++. Это базовый загрузчик, который загружает все системные классы из архива rt.jar. При этом, есть небольшое отличие между загрузкой классов из rt.jar и наших классов: когда JVM загружает классы из rt.jar, она не выполняет все этапы проверки, которые выполняются при загрузке любого другого класс-файла т.к. JVM изначально известно, что все эти классы уже проверены. Поэтому, включать в этот архив какие-либо свои файлы не стоит.

    Следующий загрузчик — это Extension classloader. Он загружает классы расширений из папки jre/lib/ext. Допустим, вы хотите, чтобы какой-то класс загружался каждый раз при старте Java машины. Для этого вы можете скопировать исходный файл класса в эту папку, и он будет автоматически загружаться.

    Еще один загрузчик — System classloader. Он загружает классы из classpath’а, который мы указали при запуске приложения.

    Процесс загрузки классов происходит по иерархии:

    • В первую очередь мы запрашиваем поиск в кэше System Class Loader (кэш системного загрузчика содержит классы, которые уже были им загружены);
    • Если класс не был найден в кэше системного загрузчика, мы смотрим кэш Extension class loader;
    • Если класс не найден в кэше загрузчика расширений, класс запрашивается у загрузчика Bootstrap.

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

    4. Структура Сlass-файлов и процесс загрузки

    Перейдем непосредственно к структуре Class-файлов.

    Один класс, написанный на Java, компилируется в один файл с расширением .class. Если в нашем Java файле лежит несколько классов, один файл Java может быть скомпилирован в несколько файлов с расширением .class — файлов байт-кода данных классов.

    Все числа, строки, указатели на классы, поля и методы хранятся в Сonstant pool — области памяти Meta space. Описание класса хранится там же и содержит имя, модификаторы, супер-класс, супер-интерфейсы, поля, методы и атрибуты. Атрибуты, в свою очередь, могут содержать любую дополнительную информацию.

    Таким образом, при загрузке классов:

    • происходит чтение класс-файла, т.е проверка корректности формата
    • создается представление класса в Constant pool (Meta space)
    • грузятся супер-классы и супер-интерфейсы; если они не будут загружены, то и сам класс не будет загружен

    5. Исполнение байт-кода на JVM

    В первую очередь, для исполнения байт-кода, JVM может его интерпретировать. Интерпретация — довольно медленный процесс. В процессе интерпретации, интерпретатор “бежит” построчно по класс-файлу и переводит его в команды, которые понятны JVM.

    Также JVM может его транслировать, т.е. скомпилировать в машинный код, который будет исполняться непосредственно на CPU.

    Команды, которые исполняются часто, не будут интерпретироваться, а сразу будут транслироваться.

    6. Компиляция

    Компилятор — это программа, которая преобразует исходные части программ, написанные на языке программирования высокого уровня, в программу на машинном языке, “понятную” компьютеру.

    • Не оптимизирующие
    • Простые оптимизирующие (Hotspot Client): работают быстро, но порождают неоптимальный код
    • Сложные оптимизирующие (Hotspot Server): производят сложные оптимизирующие преобразования прежде чем сформировать байт-код

    Также компиляторы могут классифицироваться по моменту компиляции:

    • Динамические компиляторы
      Работают одновременно с программой, что сказывается на производительности. Важно, чтобы эти компиляторы работали на коде, который часто исполняется. Во время исполнения программы JVM знает, какой код выполняется чаще всего, и, чтобы постоянно не интерпретировать его, виртуальная машина сразу переводит его в команды, которые уже будут исполняться непосредственно на процессорe.
    • Статические компиляторы
      Дольше компилируют, но порождают оптимальный код для исполнения. Из плюсов: не требуют ресурсов во время исполнения программы, каждый метод компилируется с применением оптимизаций.

    7. Организация памяти в Java

    Стек — это область памяти в Java, которая работает по схеме LIFO — “Last in — Fisrt Out” или “Последним вошел, первым вышел”.

    Он нужен для того, чтобы хранить методы. Переменные в стеке существуют до тех пор, пока выполняется метод в котором они были созданы.

    Когда вызывается любой метод в Java, создается фрейм или область памяти в стеке, и метод кладется на его вершину. Когда метод завершает выполнение, он удаляется из памяти, тем самым освобождая память для следующих методов. Если память стека будет заполнена, Java бросит исключение java.lang.StackOverFlowError. К примеру, это может произойти, если у нас будет рекурсивная функция, которая будет вызывать сама себя и памяти в стеке не будет хватать.

    Ключевые особенности стека:

    • Стек заполняется и освобождается по мере вызова и завершения новых методов
    • Доступ к этой области памяти осуществляется быстрее, чем к куче
    • Размер стека определяется операционной системой
    • Является потокобезопасным, поскольку для каждого потока создается свой отдельный стек

    Ещё одна область памяти в Java — Heap или куча. Она используется для хранения объектов и классов. Новые объекты всегда создаются в куче, а ссылки на них хранятся в стеке. Все объекты в куче имеют глобальный доступ, то есть к ним можно получить доступ из любой точки приложения.

    Куча разбита на несколько более мелких частей, называемых поколениями:

    • Young generation — область, где размещаются недавно созданные объекты
    • Old (tenured) generation — область, где хранятся “долгоживущие” объекты
    • До Java 8 существовала ещё одна область — Permanent generation — которая содержит метаинформацию о классах, методах, статических переменных. После появления Java 8 было решено хранить эту информацию отдельно, вне кучи, а именно в Meta space

    Почему отказались от Permanent generation? В первую очередь, это из-за ошибки, которая была связана с переполнением области: так как Perm имел константный размер и не мог расширяться динамически, рано или поздно память заканчивалась, кидалась ошибка, и приложение падало.

    Meta space же имеет динамический размер, и во время исполнения он может расширяться до размеров памяти JVM.

    Ключевые особенности кучи:

    • Когда эта область памяти заполняется полностью, Java бросает java.lang.OutOfMemoryError
    • Доступ к куче медленнее, чем к стеку
    • Для сбора неиспользуемых объектов работает сборщик мусора
    • Куча, в отличие от стека, не является потокобезопасной, так как любой поток может получить к ней доступ

    Основываясь на информации выше, рассмотрим, как происходит управление памятью на простом примере:

    У нас есть класс App, в котором единственный метод main состоит из:

    — примитивной переменой id типа int со значением 23
    — ссылочной переменной pName типа String со значением Jon
    — ссылочной переменной p типа person

    Как уже упоминалось, при вызове метода на вершине стека создаётся область памяти, в которой хранятся данные, необходимые этому методу для выполнения.
    В нашем случае, это ссылка на класс person: сам объект хранится в куче, а в стеке хранится ссылка. Также в стек кладется ссылка на строку, а сама строка хранится в куче в String pool. Примитив хранится непосредственно в стеке.

    Для вызова конструктора с параметрами Person (String) из метода main() в стеке, поверх предыдущего вызова main() создается в стеке отдельный фрейм, который хранит:

    this — ссылка на текущий объект
    — примитивное значение id
    — ссылочную переменную personName, которая указывает на строку в String Pool.

    После того, как мы вызвали конструктор, вызывается setPersonName(), после чего снова создается новый фрейм в стеке, где хранятся те же данные: ссылка на объект, ссылка на строку, значение переменной.

    Таким образом, когда выполнится метод setter, фрейм пропадет, стек очистится. Далее выполняется конструктор, очищается фрейм, который был создан под конструктор, после чего метод main() завершает свою работу и тоже удаляется из стека.

    Если будут вызваны другие методы, для них будут также созданы новые фреймы с контекстом этих конкретных методов.

    8. Garbage collector

    В куче работает Garbage collector — программа, работающая на виртуальной машине Java, которая избавляется от объектов, к которым невозможно получить доступ.

    Разные JVM могут иметь различные алгоритмы сборки мусора, также существуют разные сборщики мусора.

    Мы поговорим о самом простом сборщике Serial GC. Сборку мусора мы запрашиваем при помощи System.gc().

    Как уже было упомянуто выше, куча разбита на 2 области: New generation и Old generation.

    New generation (младшее поколение) включает в себя 3 региона: Eden, Survivor 0 и Survivor 1.

    Old generation включает в себя регион Tenured.

    Что происходит, когда мы создаем в Java объект?

    В первую очередь объект попадает в Eden. Если мы создали уже много объектов и в Eden уже нет места, срабатывает сборщик мусора и освобождает память. Это, так называемая, малая сборка мусора — на первом проходе он очищает область Eden и кладёт “выжившие” объекты в регион Survivor 0. Таким образом регион Eden полностью высвобождается.

    Если произошло так, что область Eden снова была заполнена, garbage collector начинает работу с областью Eden и областью Survivor 0, которая занята на данный момент. После очищения выжившие объекты попадут в другой регион — Survivor 1, а два остальных останутся чистыми. При последующей сборке мусора в качестве региона назначения опять будет выбран Survivor 0. Именно поэтому важно, чтобы один из регионов Survivor всегда был пустым.

    JVM следит за объектами, которые постоянно копируются и перемещаются из одного региона в другой. И для того, чтобы оптимизировать данный механизм, после определённого порога сборщик мусора перемещает такие объекты в регион Tenured.

    Когда в Tenured места для новых объектов не хватает, происходит полная сборка мусора — Mark-Sweep-Compact.

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

    источник

    How to Install Portable Java Runtime Environment onto USB Flash Drive

    Most computer users have heard of the Java programming language because it will be installed on a lot of machines and required on some websites. One good thing about Java is it’s cross platform and runs in it’s own self contained virtual machine, meaning the same applets and programs can be run on different operating systems such as Windows, Linux and Mac OS without using different code.

    Some users claim it slows their computer down because of the extra processes loading with Windows such as the Quick Starter process jqs.exe. One thing a Java install does do which annoys a lot of people is leave the previous versions in place to supposedly help with compatibility. The small utility JavaRa was designed to help clean out any old installation files. Exploits do appear from time to time which can potentially allow malware to be installed onto a computer if the user clicks the Yes button when visiting a website created by a hacker, but these exploits are rare and fixed pretty quickly.

    Although the Java Runtime Environment (JRE) package requires installation and there is no official portable version, it is still possible to run applets and applications without installing Java into Windows. An unofficial portable version from PortableApps.com allows you to copy Java to your USB flash drive or hard drive folder and run it from there. Here’s a gu >

    2. Download Java Portable from PortableApps.com. Once finished downloading, run the downloaded executable file and click OK -> Next -> I Agree and then you’re asked to choose an install location. By default the destination folder will show \CommonFiles\Java, add F: at the front so that it becomes F:\CommonFiles\Java and click the Install button. The latest Java installer will download which is currently around 30MB.

    3. When the Portable setup has finished, download and run the PortableApps.com jPortable Launcher tool which is a small program that can execute Java .JAR files. During the install take note of the destination folder again. Add F: in front so that the destination folder becomes F:\JavaPortableLauncher and click the Install button.

    4. To run a Java applet or application, open the F: drive and execute the F:\JavaPortableLauncher\JavaPortableLauncher.exe file which will open a file dialog asking you to select the .JAR file of the applet or program you want to run. If you are getting a “jPortable Launcher cannot be started…” error, it means that you installed Java Portable at the wrong location in step 2. Make sure that it is installed in \CommonFiles\Java.

    You cannot use this method with currently installed software that requires Java to function like LibreOffice or jDownloader or Java applets in web browsers. If you try to open a webpage in an installed browser which requires Java then you’ll just be told it needs to be installed. The torrent client Vuze/Azureus did at least ask for the location of the Java files on install and worked using the portable Java.

    The good thing is PortableApps.com have made this version of Java compatible with their portable applications that require or use Java such as LibreOffice or Firefox. Just make sure to have CommonFiles in the same folder as the portable application folder, e.g; F:\folder1\CommonFiles\Java and F:\folder1\FirefoxPortable.

    The hugely popular download manager jDownloader is programmed in Java and will obviously need a Java runtime installation to work. Although not officially available at PortableApps.com, it can easily be used in a portable way with the above method. Simply download the MultiOS zip file from “Other” on the jDownloader download page and extract it to your USB flash drive or hard drive folder. Now simply launch JavaPortableLauncher and locate the jDownloader.jar file.

    To launch jDownloader directly from a shortcut so you don’t need to open the JAR file manually every time requires a few extra steps, you need to:

    1. Copy the contents of the JavaPortableLauncher folder to the jDownloader folder.

    2. Create a shortcut of JavaPortableLauncher.exe, right click on the shortcut -> Properties, then append “jDownloader.jar” in the Target box. Create the shortcut AFTER copying the jDownloader folder to its final location or the paths in the shortcut will be incorrect.

    The CommonFiles folder HAS to be one folder level up from where you have placed the JavaPortableLauncher.exe. For example, if you have:

    The CommonFiles folder will be:

    Using this method you can have a portable jDownloader folder with Java included which can be placed in any hard drive folder or external USB drive. Obviously you can do this with many other Java based applications not just jDownloader.

    источник

    Читайте также:  Установка квалифицированного сертификата казначейство

    Добавить комментарий