Показаны сообщения с ярлыком javaee. Показать все сообщения
Показаны сообщения с ярлыком javaee. Показать все сообщения

вторник, 22 сентября 2009 г.

glassfish thread pool

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


для начала необходимо его создать, через веб консоль администрирования и дать ему имя:
Configuration -> Thread Pools -> New


использовать так:
...
import com.sun.enterprise.connectors.ConnectorRuntimeException;
import com.sun.enterprise.connectors.work.WorkManagerFactory;
import javax.resource.spi.work.Work;
import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkManager;
...
    try {
        WorkManager workManager = WorkManagerFactory.getWorkManager("threadpoolname");
        Work work = new Work() {
            @Override
            public void release() {
//вызывается если необходимо остановить тред
            }
 
            @Override
            public void run() {
//код, который надо распараллелить
            }
        };
        workManager.scheduleWork(work);
    } catch (WorkException e) {
//что-то сделать
} catch (ConnectorRuntimeException e) {
//что-то сделать
...
}
и не забудьте подключить библиотеку glassfish_dir/lib/appserv-rt.jar

четверг, 17 сентября 2009 г.

жава ее Шедулер своими руками

Все мы иногда что-нибудь планируем, ставим себе галочки в уме что утром будем просыпаться и делать зарядку или что завтра ляжем спать не в два а часов в одинадцать. так вот, если нифига не получается - значит плохой планировщик задач. сегодня напишем свой планировщик задач для javaee app-сервера:
package myproject.ejb;

import java.util.Date;
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

@Stateless
public class UsualBean implements UsualLocal {

@Resource
TimerService timerService;

private static long intervalDuration = 3000;

private void makeMeHappy() {
System.out.println("i am so happy at " + new Date());
}

public void createTimer(long intervalDuration) {
//это что бы два раза не выполнить одно и то же задание
for (Object o : timerService.getTimers()) {
if (o instanceof Timer) {
((Timer) o).cancel();
}
}

this.intervalDuration = intervalDuration;
//обратите внимание на второй параметр, это может быть любой Serializable объект
Timer timer = timerService.createTimer(intervalDuration, "all your base are belong to us");
}

@Timeout
private void timeout(Timer timer) {
this.makeMeHappy();
//таймер срабатывает один раз, мне же надо через определенный интервал
timerService.createTimer(intervalDuration, timer.getInfo());
}
}


теперь осталось только запустить этот шедуллер методом createTimer, можно при старте app-сервера

вторник, 15 сентября 2009 г.

Как выполнить определенный код при старте app-сервера

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

Вообщем надо поправить файл web.xml , если вы не используете веб компоненту в своем энтерпрайз проекте, придется создать пустой проект с одним этим файлеком.


<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xsi="http://www.w3.org/2001/XMLSchema-instance" schemalocation="http://java.sun.co">
<listener>
<listener-class>myproject.ejb.MyContextListener</listener-class>
</listener>
</web-app>

Это тот класс, методы которого будут вызываться, когда изменяется контекст сервлета.

package myproject.ejb.MyContextListener;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyContextListener implements ServletContextListener {

public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContextListener::contextDestroyed");
}

public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContextListener::contextInitialized");
}
}


как-то так :)

пятница, 10 июля 2009 г.

manual javaee realm

Недавно я писал о том, как настроить jdbc realm в glassfish. Сейчас я попытаюсь рассказать, о том, как написать свой realm самому.

Итак, что же такое этот realm?
Realm - это такой механизм, отвечающий за аутентификацию пользователя на сервере приложений. Когда пользователь (точнее говорить principal) пытается получить доступ к какому-либо ресурсу сервера приложений, если для этого нужна авторизация, то realm используется для получения списка групп, в которых состоит пользователь. На основании этого списка решается - позволено ли данному пользователю воспользоваться данным ресурсом (будь то java-bean, jdbc-datasource и т.д.).

В совокупности с JAAS фреймворком они представляют собой подсистему аутентификации glassfish`а.

Для того, что бы написать свой realm для glassfish v2.1 необходимо реализовать два класса:

com.sun.appserv.security.AppservRealm
com.sun.appserv.security.AppservPasswordLoginModule

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

и добавить информацию о них в:

domain_dir/config/domain.xml
domain_dir/config/login.conf

замечание: для того что бы эти классы были видны в IDE я подкинул им пару jar-ов из glassfish`a, которые после билда можно исключить из списка файлов, т.к. они уже есть на сервере приложений:
glassfish_dir/lib/appserv-ext.jar
glassfish_dir/lib/appserv-rt.jar

среда, 24 июня 2009 г.

Java Interceptors

Вместе с появлением EJB3.0 в JavaEE появилась очень полезная штука - Interceptors - специальные классы, которые могут перехватывать вызов методов заданного класса.
Для чего это может быть полезно? Если у вас есть сложное приложение и изменение его кода - очень трудоемкий процесс, то для некоторого класса задач можно использовать Interceptor`ы

Например:
  • для изменения некоторых бизнес методов на лету (в т.ч. входных параметров, исключений)
  • для мониторинга производительности приложения
  • для аудита различных событий

Пример:



public class AuditInterceptor {

@AroundInvoke
public Object trace(InvocationContext invocationContext) throws Exception{
System.out.println("Object: " + invocationContext.getTarget().getClass().getName());
System.out.println("Method: " + invocationContext.getMethod());

System.out.println("Parameters:");
for (Object p : invocationContext.getParameters()) {
System.out.println("[" + p.getClass().getName() + "] " + p);
}

return invocationContext.proceed();
}
}


Этот класс может перехватывать события для следуюющего бина:


@Stateless
@Interceptors({AuditInterceptor.class})
public class ComplexBean implements ComplexRemote {

public String makeMeHappy(String param1) {
//some code
}
}


Т.е. при каждом вызове любого метода для этого бина выплонится метод AuditInterceptor.trace, который в свою очередь может запустить(а может и нет, как вам будет угодно) нужный метод данного бина


воскресенье, 7 июня 2009 г.

полезные аннотации JPA

Вот очень полезные аннотации, при помощи которых можно реализовать java trigger
  • @PostLoad
  • @PrePersist
  • @PostPersist
  • @PreUpdate
  • @PostUpdate
  • @PreRemove
  • @PostRemove
например:


@Entity
public class Human implements Serializable {
...
@Basic
@Column
private String hello;
...
public String getHello() {
return hello;
}
public void setHello(String hello) {
this.hello = hello;
}
...
@PrePersist
@PreUpdate
private void preModify () {
hello = hello.trim().toLowerCase();
}
...
}

Если в @Entity перед каким-либо полем установить аннотацию @Transient, то это поле не будет добавляться в хранилище при вызове em.persist(entity);
Бывает полезно если в entity есть какие то рабочие поля, которые не представляют ни какого поля в хранилище данных, но нужны для реализации бизнес логики приложения