Апплет в Java (в запросах часто пишут «аплет») — это класс, унаследованный от java.applet.Applet или javax.swing.JApplet, который браузер скачивал со страницы и запускал в своей Java-машине через плагин Java Plug-in. У апплета нет метода main: создает объект и вызывает его методы init, start, stop, destroy и paint не программист, а браузер.
Содержание
- Апплет, приложение, сервлет, Web Start: не путать
- Как работал апплет
- Минимальный апплет и что с ним происходит сегодня
- Почему апплеты устарели
- Чем заменить апплет сегодня
- Перенос апплета в настольное приложение
- Как найти апплеты в старом проекте
- Если не получилось
- Выводы
- Где применяется / связь с практикой
- FAQ
Сегодня это историческая технология. Ни один современный браузер апплеты не запускает, API помечен устаревшим в JDK 9, помечен к удалению в JDK 17 и удален в JDK 26 (JEP 504). Ниже — как апплет был устроен, почему от него отказались и что взять вместо него, если вам достался старый код.
Слово «апплет» употребляют и в других смыслах: так называют, например, модули панели управления Windows (файлы .cpl). В этой статье речь только о Java.
Апплет, приложение, сервлет, Web Start: не путать
Эти понятия часто смешивают, хотя запускаются они по-разному.
| Что | Где выполняется | Кто запускает | Точка входа | Статус в 2026 |
|---|---|---|---|---|
| Апплет | JVM внутри браузера (плагин) | браузер по тегу страницы | init()/start() |
удален из JDK 26 |
| Настольное приложение | JVM на компьютере пользователя | пользователь, ярлык, инсталлятор | main |
актуально (Swing, JavaFX) |
| Сервлет | JVM на сервере (Tomcat, Jetty) | контейнер сервлетов по HTTP-запросу | service()/doGet() |
актуально (Jakarta Servlet) |
| Java Web Start | JVM на компьютере, приложение скачано по ссылке .jnlp |
лаунчер javaws |
main |
удален из Oracle JDK 11 |
| JavaScript | движок браузера | браузер | скрипт страницы | стандарт веба |
Главное отличие апплета от приложения — не код, а хозяин жизненного цикла. Приложение само решает, когда начать и закончить работу. Апплетом управлял браузер: загрузил страницу — создал объект, ушли со страницы — остановил.
Как работал апплет
Страница подключала скомпилированный класс тегом <applet>, параметры передавались тегами <param>:
<applet code="HelloApplet.class" width="300" height="100">
<param name="name" value="Otus">
Ваш браузер не поддерживает Java-апплеты.
</applet>
Браузер скачивал HelloApplet.class (или JAR-архив из атрибута archive) с того же сервера, что и страница, и передавал плагину. Текст между тегами показывался, если Java не было. Тег <applet> признан устаревшим еще в HTML 4.01, а в HTML5 он исключен из стандарта; позже апплеты подключали через <object> или <embed>.
Жизненный цикл выглядел так:
| Метод | Когда вызывал браузер | Что обычно делали | Аналог в Swing-приложении |
|---|---|---|---|
init() |
один раз после загрузки | читали параметры, создавали компоненты | конструктор окна или main |
start() |
после init() и при возврате на страницу |
запускали анимацию, потоки | показ окна, windowActivated |
paint(Graphics) |
когда область нужно перерисовать | рисовали | paintComponent в JPanel |
stop() |
при уходе со страницы | останавливали потоки | windowDeactivated, сворачивание |
destroy() |
перед выгрузкой апплета | освобождали ресурсы | windowClosing, завершение |
Точный момент вызова stop() и destroy() зависел от браузера и версии плагина: одни выгружали апплет при уходе со страницы, другие держали его в кеше. Поэтому на «гарантированный» вызов destroy() полагаться было нельзя.
Неподписанный апплет работал в песочнице: не читал локальные файлы и соединялся по сети только с сервером, с которого был загружен. Подписанный апплет с согласия пользователя получал больше прав — и именно это стало одной из главных проблем.
Минимальный апплет и что с ним происходит сегодня
Классический пример, переписанный с явными импортами:
import java.applet.Applet;
import java.awt.Graphics;
public class HelloApplet extends Applet {
@Override
public void init() {
System.out.println("init: param name = " + getParameter("name"));
}
@Override
public void paint(Graphics g) {
g.drawString("Привет, мир", 25, 50);
}
}
В браузере с плагином на экране появлялась надпись «Привет, мир», а getParameter("name") возвращал значение из тега <param>. Проверим, что с этим кодом происходит на JDK 25 (Temurin 25.0.4, проверено 24.09.2026). Он еще компилируется, но с предупреждением:
HelloApplet.java:4: warning: [removal] Applet in java.applet has been deprecated and marked for removal
public class HelloApplet extends Applet {
^
1 warning
Запустить его как обычную программу нельзя, потому что метода main нет:
Error: Main method not found in class HelloApplet, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
А если создать объект апплета в среде без экрана (сервер, контейнер, CI), конструктор Applet бросит java.awt.HeadlessException. Утилита appletviewer, которой раньше смотрели апплеты без браузера, удалена из JDK еще в версии 11. Итог: на JDK 25 код апплета компилируется, но запустить его как апплет штатными средствами уже нечем. На JDK 26 (проверено на Temurin 26.0.2) пакета java.applet больше нет, и обычная компиляция падает:
HelloApplet.java:1: error: package java.applet does not exist
import java.applet.Applet;
^
С ключом javac --release 25 тот же файл на JDK 26 еще соберется (компилятор берет описание API 25-й версии), но запуск на JDK 26 закончится java.lang.NoClassDefFoundError: java/applet/Applet: классов апплета в самой среде выполнения уже нет.
Почему апплеты устарели
Причин несколько, и ни одна из них по отдельности не была бы смертельной:
- Безопасность. Плагин Java был одной из самых атакуемых частей браузера: уязвимости позволяли выйти из песочницы и выполнить код на компьютере пользователя. Oracle ужесточала правила (по умолчанию запускались только подписанные апплеты, пользователь видел предупреждения), но это било и по легальным сайтам.
- Конец плагинов NPAPI. Браузеры отказались от старой модели плагинов: Chrome — в 2015 году, Firefox — в 2017-м (кроме Flash), Safari — позже. Без плагина апплет просто не запускается.
- Мобильные устройства. На iOS и Android Java-апплеты в браузере не работали никогда.
- Веб догнал. HTML5, Canvas, WebGL, WebSocket и быстрый JavaScript закрыли почти все задачи, ради которых подключали апплеты: графику, игры, интерактивные схемы.
Хронология в самой Java:
| Год | Версия / событие | Что произошло |
|---|---|---|
| 1995 | первая публичная Java | апплеты — главный сценарий запуска Java в вебе |
| 2017 | JDK 9, JEP 289 | Applet API помечен @Deprecated |
| 2018 | JDK 11 | из Oracle JDK убраны Java Plug-in и Java Web Start, из JDK — appletviewer |
| 2021 | JDK 17, JEP 398 | Applet API помечен к удалению (forRemoval = true) |
| 2026 | JDK 26, JEP 504 | Applet API удален |
По JEP 504 удаляется пакет java.applet целиком (Applet, AppletContext, AppletStub, AudioClip), классы javax.swing.JApplet и java.beans.AppletInitializer и связанные с апплетами методы в java.beans.Beans и javax.swing.RepaintManager. Еще одна причина удаления — песочница апплета держалась на Security Manager, а его окончательно отключили в JDK 24. Значит, JDK 25 — последняя LTS-версия, в которой Applet API есть в самой среде выполнения.
Чем заменить апплет сегодня
Выбор зависит от того, что апплет делал на самом деле:
| Что делал апплет | Что взять сейчас | Когда иначе |
|---|---|---|
| Интерактивная графика, игра, визуализация на странице | HTML5 Canvas / WebGL + JavaScript или TypeScript | если логика большая и уже на Java — компиляция Java в JavaScript или WebAssembly (TeaVM, J2CL) |
| Форма, калькулятор, работа с данными сервера | веб-приложение: фронтенд на JS, бэкенд на Java (Spring Boot, Jakarta EE) | — |
| Полноценная программа, которую «запускали с сайта» | настольное приложение на Swing или JavaFX, упакованное jpackage в инсталлятор |
если нужно автообновление по ссылке — сторонние реализации JNLP |
| Доступ к локальным файлам, устройствам, подпись документов | настольное приложение или локальный агент, с которым страница общается по HTTP | браузерные API (File System Access, WebUSB) — если хватает их возможностей и поддержки браузеров |
| Старый корпоративный апплет, который нельзя переписать сразу | изолированная виртуальная машина со старыми браузером и Java 8, без выхода в интернет | эмуляторы JVM в браузере — как временная мера |
Последняя строка — именно временная мера. Старый плагин не получает исправлений, поэтому держать его на рабочем компьютере с доступом в интернет рискованно.
Перенос апплета в настольное приложение
Если апплет был самостоятельной программой, быстрее всего превратить его в Swing-приложение. Порядок такой:
- Вынести рисование из
paint()в отдельный метод или вpaintComponent()наследникаJPanel. - Код из
init()перенести в конструктор илиmain. - Параметры
<param>заменить аргументами командной строки, системными свойствами или файлом настроек. - Создать
JFrame, задать размер,setDefaultCloseOperationи вызватьsetVisible(true)— в апплете этим управлял браузер. - Работу с окном выполнять в потоке событий через
SwingUtilities.invokeLater.
Тот же «Привет, мир» в виде приложения:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class HelloDesktop {
// Логика рисования вынесена из paint() апплета в отдельный метод
static void draw(Graphics g, String name) {
g.setColor(Color.BLACK);
g.drawString("Привет, " + name, 25, 50);
}
static class HelloPanel extends JPanel {
private final String name;
HelloPanel(String name) { this.name = name; }
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g, name);
}
}
public static void main(String[] args) throws Exception {
// Бывший <param name="name" value="..."> теперь аргумент запуска
String name = args.length > 0 ? args[0] : "мир";
if (GraphicsEnvironment.isHeadless()) {
// Сервер или контейнер без экрана: рисуем в картинку
BufferedImage img = new BufferedImage(300, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, 300, 100);
draw(g, name);
g.dispose();
ImageIO.write(img, "png", new File("hello.png"));
System.out.println("headless: hello.png " + img.getWidth() + "x" + img.getHeight());
return;
}
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Hello");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new HelloPanel(name));
frame.setSize(300, 100);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
На компьютере с экраном команда java HelloDesktop.java откроет окно 300×100 с надписью «Привет, мир». В среде без экрана программа не падает, а сохраняет ту же надпись в hello.png и печатает:
headless: hello.png 300x100
Ветка без экрана добавлена специально: она показывает главный прием переноса. Логика рисования (draw) больше не привязана ни к апплету, ни к окну, поэтому ее можно вызвать и из JPanel, и для картинки, и из теста.
Как найти апплеты в старом проекте
Перед переходом на JDK 26 и новее стоит проверить, не осталось ли в коде и зависимостях апплетов. В JDK есть утилита jdeprscan, которая ищет использование API, помеченного к удалению. Пример на JAR с классами из статьи (JDK 25):
jar cf legacy.jar *.class
jdeprscan --release 25 --for-removal legacy.jar
Jar file legacy.jar:
class HelloApplet extends deprecated class java/applet/Applet (forRemoval=true)
class HelloApplet uses deprecated class java/applet/Applet (forRemoval=true)
HelloDesktop в отчет не попал: он использует только Swing, который остается в JDK. Второй способ — jdeps -verbose:class legacy.jar, вывод которого можно отфильтровать по java.applet и JApplet. Сканируйте не только свой код, но и сторонние JAR: апплетный класс мог приехать с библиотекой.
Если не получилось
- Страница показывает текст вместо апплета или пустую область. Браузер не поддерживает плагины. Это не исправить настройкой — нужен перенос или изолированная среда со старым ПО.
Main method not found in class .... Вы запускаете апплет как приложение. ДобавьтеmainсJFrame, как в примере выше.java.awt.HeadlessExceptionпри создании объекта. Код с окнами запущен на сервере или в контейнере без экрана. Отделите логику от окна или проверяйтеGraphicsEnvironment.isHeadless().- После обновления JDK сборка падает на
java.appletилиJApplet. Вы на JDK 26 или новее.javac --release 25поможет только собрать код: запускать его все равно придется на JDK 25 или старше, иначе будетNoClassDefFoundError: java/applet/Applet. Это временная мера, планируйте перенос: 25 — последняя LTS с этим API.
Выводы
- Апплет — Java-класс без
main, которым управлял браузер через плагин; от приложения его отличает хозяин жизненного цикла. - Апплеты ушли из-за уязвимостей плагина, отказа браузеров от NPAPI, отсутствия на мобильных и развития HTML5.
- Applet API устарел в JDK 9, помечен к удалению в JDK 17 и удален в JDK 26 по JEP 504; JDK 25 — последняя LTS, где такой код и компилируется, и запускается.
- Замена зависит от задачи: веб-интерфейс на JavaScript с бэкендом на Java, настольное приложение на Swing/JavaFX или изолированная среда для legacy.
- Старые апплеты в проекте ищут утилитами
jdeprscanиjdepsиз состава JDK.
Где применяется / связь с практикой
Апплеты сегодня встречаются только в сопровождении старых систем, но задача их переноса опирается на базовые навыки Java: классы и наследование, работа с графикой и Swing, сборка и запуск программ, понимание версий JDK. Историю языка и платформы для крупных систем можно посмотреть в статье о Java EE и ее развитии.
Освойте тему на практике
Если хотите системно освоить язык с нуля до уверенного уровня, посмотрите курс «Java разработчик. Базовый уровень». Попробовать формат и задать вопросы преподавателям можно на бесплатных открытых уроках.
FAQ
Можно ли сейчас запустить старый апплет?
Только в изолированной среде со старым браузером, поддерживающим плагины, и Java 8 с плагином, либо через эмуляторы JVM в браузере. Для рабочей эксплуатации это не годится: старый плагин не получает исправлений безопасности.
Чем апплет отличался от JavaScript?
Это разные языки и разные среды: апплет — скомпилированный байт-код Java, который выполнял плагин, JavaScript — язык самого браузера. Общее у них только то, что оба запускались со страницы.
Нужно ли изучать апплеты новичку в Java?
Нет. Достаточно знать, что это было и почему ушло, чтобы узнать апплет в старом коде. Время лучше потратить на Swing или JavaFX для настольных программ и на веб-разработку на Java.



