То, на что вы наткнулись, является фундаментальной проблемой, касающейся использования Java и "враждебных" приложений.
Это фундаментальная проблема не только на уровне Java EE, но и на уровне ядра JVM. Типичные доступные JVM имеют все виды проблем с загрузкой «небезопасного кода». Типичная JVM из-за утечек памяти, утечек из-за загрузчиков классов, исчерпания ресурсов и неочищенных потоков приводит к тому, что типичная JVM просто недостаточно надежна, чтобы хорошо обрабатывать плохо работающий код в общей среде.
Простой пример - исчерпание памяти кучи Java. Как правило, NOBODY (и никем, я специально имею в виду базовую библиотеку Java и почти все остальные сторонние библиотеки) ловит исключения OutOfMemory. Есть редкие, которые делают, но даже они мало что могут с этим поделать. Типичный код обрабатывает исключения, которые они «ожидают» обработать, но позволяют другим провалиться. Исключения времени выполнения (одним из которых является OOM) будут счастливо подниматься в стеке вызовов вплоть до самого верха, оставляя за собой обломки непроверенного кода критического пути, оставляя все виды вещей в неизвестном состоянии.
Такие вещи, как конструкторы или статические инициализаторы, которые «не могут потерпеть неудачу», оставляя после себя неинициализированные члены класса, которые «никогда не равны нулю». Эти поврежденные классы просто не знают, что они повреждены. Никто не знает, что они повреждены, и нет способа их почистить. Куча, попадающая в OOM, представляет собой небезопасный образ, и в значительной степени ее необходимо перезапустить (если, конечно, вы сами не написали или проверили ВСЕ код, чего, естественно, не будете - кто будет?).
Теперь вполне могут существовать JVM от конкретного поставщика, которые лучше ведут себя и дают вам лучший контроль. Те, что основаны на JVM Sun / Oracle (то есть большинство из них), не делают.
Итак, это не обязательно проблема Java EE, это проблема JVM.
Хостинг враждебного кода в JVM - плохая идея. Единственный способ, которым это практично, - это если вы размещаете язык сценариев, и этот язык сценариев реализует некоторый вид управления ресурсами. Это можно сделать, и вы можете вначале настроить существующие (JavaScript, Groovy, JPython, JRuby). Тот факт, что эти языки предоставляют пользователям прямой доступ к библиотекам Java, делает их потенциально опасными, поэтому вам, возможно, придется ограничить это только аспектами, заключенными в обработчики сценариев. Однако в этот момент возникает вопрос «зачем вообще использовать Java».
Вы заметите, что Google App Engine не выполняет ничего из этого. Он создает отдельную JVM для каждого запускаемого приложения, но даже в этом случае он значительно ограничивает то, что может быть сделано в этих JVM, особенно с помощью существующей модели безопасности Java. Различие здесь в том, что эти экземпляры имеют тенденцию быть «долгоживущими», чтобы не переносить затраты на обработку при запуске и завершении работы. Я должен сказать, что они ДОЛЖНЫ быть долгоживущими, а те, кто этого не делают, несут эти расходы.
Вы можете сделать несколько экземпляров JVM самостоятельно, предоставить им немного инфраструктуры для обработки запросов на логику, предоставить им собственную логику загрузчика классов, чтобы попытаться защитить от утечек загрузчика классов, и минимально позволить убить экземпляры (они просто процесс) если хочешь. Это может сработать и, вероятно, сработает «хорошо» в зависимости от степени детализации вызовов и времени «запуска» для вашей логики. Время запуска будет минимально загружать классы для логики от запуска к запуску, что само по себе может сделать это плохой идеей. И это, конечно, не будет "Java EE". Java EE не настроен на подобные вещи. Но вам не ясно, какие функции Java EE вы просматриваете.
По сути, это то, что делает Apache и "mod_php". Несколько экземпляров, таких как процессы, индивидуально обрабатывающие запросы, с плохим поведением, когда их убивают по мере необходимости. Вот почему PHP распространен в бизнесе виртуального хостинга. В этой структуре это в основном "безопасно".