Category Archives: Java
Если вам нужно что-то постоянно передеплоить, а то и перезапускать, и вам надоело ждать по 3 минуты, когда стартует JBoss Portal, не отчаивайтесь ! Используйте JRebel.
Эта штука реализует подход, более продвинутый, чем HotSwap, и можно не только менять код существующих методов в классах, но и дописывать новые, добавлять филды (в т.ч. статические), конструкторы итд. Для сервлет-контейнеров и app серверов есть специальные приблуды типа корректной обработки релоада не только джаваклассов, но и jsp, Hibernate proxy, в общем много чего.
Последнюю версию с таблэткой можно найти на том же rutracker.
bin/jrebel-app-config.cmd поможет вам настроить Вашу любимую IDE. Только учтите, что при создании run_jrebel.bat вам, скорее всего, нужно будет запускать не run.bat а run_jpda.bat (вы же хотите отлаживать свой код, не так ли?).
Единственный вопрос, остающийся после визарда – что должен содержать rebel.xml и вообще зачем он нужен ? Этот файл должен быть внутри деплоящегося модуля (jar, war) и должен содержать пути к классам, которые могут обновляться. JRebel при первой загрузке модуля смотрит его и начинает мониторить указанные директории. Если классы/jsp в них обновляются (по timestamp), он их перезагружает из этих директорий. В jar этот xml файл должен лежать в корне. Таким образом,
portal-core-lib.jar
> META-INF
> classes
> > some stuff
> rebel.xml
А в rebel.xml вот такая борода:
<?xml version="1.0" encoding="UTF-8" ?> <application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd"> <classpath> <dir name="C:/elwood/work/portal/core/out/production/portal-core-lib" /> </classpath> </application> |
HotSwap в IDEA можно (и даже нужно, скорее всего, поскольку он не будет работать корректно) отключить. Классы помечаются для релоада после их перекомпиляции посредством Ctrl-Shift-F9 (compile one class).
Релоадятся классы не сразу, а при доступе приложения к ним.
Обычно считается, что фреймворки для разработки полезны тем, что предоставляют возможность программисту пользоваться некой готовой инфраструктурой. То есть основной плюс – в том, что ДОБАВЛЯЮТСЯ ВОЗМОЖНОСТИ использовать готовое. Но мне в последнее время кажется, что главное преимущество даже не в этом, а в том, что фреймворки, как правило, помимо дополнительных возможностей также накладывают существенные ограничения на код, который будет в рамках него работать.
Пример – Spring MVC предлагает только несколько стандартных способов написать обработчик запроса. Хочешь обработать запрос – пропиши маппинг и добавь метод в контроллер. Хочешь датабиндинг – используй @ModelAttribute. Почему это хорошо ? Потому что разработчику нужно меньше шевелить мозгами, раздумывая над тем, как бы лучше запрограммировать этот кусочек. Больше времени останется на продумывание более важных вещей. Плюс к этому, все, кто знакомы со Spring MVC, будут с первого взгляда понимать то, что хотел сказать программист Вася, написавший этот код года два назад. Значит, добавление ограничений положительно влияет на процесс разработки ? Получается, так.
Действительно, имея широкий набор возможностей, тяжело научиться их правильно использовать. Причем, как правило, сначала учишься использовать правильно, набивая шишки, и попутно придумываешь правила сам. Некий кодстайл, паттерны для того, чтобы писать корректный код, не думая о деталях. Так я учился в своё время языку С++. Читая описание того, что такое header-файл, я нигде не мог найти аргументированных правил по его использованию. Сейчас такая литература появилась в изобилии, но в то время у меня еще не было интернета. И я долгое время не знал, как оформлять h-файлы и как их инклудить в cpp – что именно должно быть в h-файле, а что – в cpp, можно ли инклудить h-файл в другой h-файл; если cpp-файл использует h-файл, зависящий от другого, то нужно ли в cpp-файл включать эту зависимость итд. Поэтому сидел и морщил ум на тему, как же сделать правильно. А всё потому, что С++ предоставляет множество способов сделать это НЕправильно, а очевидности, очевидные для опытных программистов, далеко не так очевидны для новичков. Аналогичные шишки приходилось набивать и на других платформах. C#, к примеру, заставил меня призадуматься о стратегии обработки исключений и особенно о корректной реализации IDisposable в иерархии классов.
Поэтому хороший фреймворк должен не только предоставлять пачку возможностей, но и набор несложных правил о том, как, собственно, писать код. Чтобы лезть в декомпилятор/исходники/дебагер приходилось как можно реже. Codestyle & FAQ – идеальные форматы для такой информации.
Часто при использовании EJB возникает необходимость получить пропертисы объекта одним запросом, но проперти помечено как LAZY и исправлять на EAGER нежелательно. Выход в данной ситуации стандартными методами есть только один : опуститься на уровень native query. Ну или если хочется убить производительность, то разместить цикл опроса Lazy полей (это приведет к генерации циклических запросов к СУБД, и, соответственно, к деградации перформанса).Что же делать ? На помощь приходит возможность HQL указать хибернейту, что некоторые пропертисы или коллекции необходимо подгрузить сразу, не откладывая момент вызова lazy-прокси. Например,
select u from User u
inner join fetch u.company c
подгрузит присоединяемое свойство за один запрос в джойне так, как бы это было реализовано, используй мы native query.
Или
from Document fetch all properties
сделает все то же для всех свойств объекта Document.
После того, как все заработало, не поленитесь проверить в профайлере запросов, что сгенерировал хибер и какие запросы были выполнены. Возможно, что-то пошло не так, и запросы не отвечают требованиям производительности. Если это случилось – что ж, в любом случае у вас еще остаются native query 🙂
В общем, теперь можно не париться и объявлять все пропертисы по умолчанию как fetchMode = LAZY.
Подробнее синтаксис описан в документе http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html
2