В общих чертах проблема заключается в модели безопасности Java, которая фактически пытается предотвратить повторную загрузку уже загруженного класса.
Конечно, Java с самого начала поддерживала динамическую загрузку классов, но трудно перезагружать классы.
Было опасно (и по уважительной причине), что запущенное Java-приложение было внедрено в новый класс с вредоносным кодом. Например, взломанная реализация java.lang.String, поступающая из Интернета, которая вместо создания строки удаляет некоторый случайный файл, вызывая метод length ().
Таким образом, способ, которым Java был задуман (и я предполагаю, что .NET CLR в результате, потому что это было очень "вдохновлено" в JVM), состоял в том, чтобы предотвратить загрузку уже загруженного класса той же виртуальной машиной.
Они предложили механизм для переопределения этой «функции». Загрузчики классов, но опять-таки правила для загрузчиков классов заключались в том, что они должны запросить разрешение у «родительского» загрузчика классов, прежде чем пытаться загрузить новый класс, если родитель уже загрузил класс, новый класс игнорируется.
Например, я использовал загрузчики классов, которые загружают классы из LDAP или RDBMS
Горячее развертывание становится необходимостью в мире Java, когда сервер приложений становится основным для Java EE (а также создает потребность в микроконтейнерах, таких как spring, чтобы избежать такого рода нагрузки).
Перезапуск всего сервера приложений после каждой компиляции сводит с ума любого.
Таким образом, провайдер сервера приложений, предлагает этот «пользовательский» загрузчик классов, чтобы помочь горячему развертыванию, и, используя файл конфигурации, такое поведение ДОЛЖНО быть отключено при установке в производстве. Но вы должны использовать тонны памяти при разработке. Поэтому хороший способ сделать это - перезапускать каждые 3-4 развертывания.
Этого не происходит с другими языками, которые были разработаны с самого начала для загрузки своих классов.
Например, в Ruby вы можете даже добавить методы к запущенному классу, переопределить метод во время выполнения или даже добавить один метод к уникальному конкретному объекту.
Компромисс в подобных средах - это, конечно, память и скорость.
Надеюсь, это поможет.
EDIT
Некоторое время назад я обнаружил этот продукт, который обещает сделать перезагрузку максимально простой. Я не помню ссылку, когда впервые написал этот ответ, и я знаю.
Это JavaRebel от ZeroTurnaround