wtorek, 27 listopada 2007

Prywatne jak publiczne...

Czy można odczytać i nawet modyfikować w Javie zmienne prywatne?
Okazuje się, że tak...
Kluczem do tego jest mechanizm refleksji, który pozwala dobrać się do informacji o klasie i je zmodyfikować:

import java.lang.reflect.Field;

class FieldTest {
private String privateString = "Hello, World!";
}

public class privTest {

public static void main(String args[]) throws Exception {
FieldTest fieldTest = new FieldTest();

Field f = FieldTest.class.getDeclaredField("privateString");
System.out.println("Private Field: " + f);

f.setAccessible(true);
System.out.println(f.get(fieldTest));

f.set(fieldTest, "bulba");
System.out.println(f.get(fieldTest));
}

}


Co my tu mamy? Deklarujemy sobie klasę FieldTest z jednym prywatnym stringiem...
Właściwy kod jest w klasie privTest. Pobieramy obiekt reprezentujący informacje o polu 'privateString' a następnie zmieniamy je na dostępne przez setAccessible...
i już możemy robić z prywatną zmienną to co nam się podoba :)
Podobnie można zmodyfikować dostęp do konstruktorów i metod prywatnych.

Quartz c.d.

W poprzednim poście XML definiował mamy 4 powiązane ze sobą obiekty.
Zaczniemy od końca :)

1. Scheduler:
Jak można się domyślać, do zarządzania wszystkimi zdarzeniami potrzebujemy jednego z nich. Jest to obiekt 'scheduler' klasy org.springframework.scheduling.quartz.SchedulerFactoryBean. Tak więc dzięki temu, że w bibliotece Spring 2.0 mamy wsparcie dla Quartz możemy go tutaj wykorzystać.
Ponieważ chcemy, żeby zarządzanie zdarzeniami było włączone automatycznie po starcie aplikacji i czekało na zakończenie zadań przed zamknięciem, to ustawiamy atrybuty autoStartup i waitForJobsToCompleteOnShutdown na true.
Właciwosć 'triggers' tego obiektu służy do zdefiniowania samych zdarzeń.
U nas lista ta zawiera odwołanie tylko do jednego obiektu, dummyCronTrigger który jest zdefiniowany wyżej.

2. dummyCronTrigger - wyzwalacz zdarzenia.
Ponieważ chciałem, żeby zdarzenie było wywoływane co 10 sekund, musiałem użyć triggera bazującego na wyrażeniu polecenia Linuxowego cron.
W tym przypadku wygląda ono tak: 0/10 * * * * ?
Właściwość jobDetail ustawiamy na dummyJobDetail, czyli obiekt, który definiuje ma konkretne zadanie.

3. dummyJobDetails - służy tylko do wskazania metody obiektu, który wykona nasze zadanie.

4. outdatetProjectsMailSender to właściwy obiekt wykonujący nasze zadanie.
Przy implementacji zadania należy zwrócić uwagę, że ta metoda nie powinna rzucać wyjątków innych niż JobExecutionException.

Na koniec link do tutoriala, który przydał mi się do zrozumienia tego tematu:
http://www.lucianofiandesio.com/javatales/qtzfuse.html

piątek, 2 listopada 2007

Quartz cz. 1

Ostatnio miałem zintegrować Quartz-a z aplikacją webową działającą na Tomcat-cie. Quartz to biblioteka służąca do zarządzania zdarzeniami, które mają się wykonywać w pewnych, określonych momentach czasu. Te 'momenty' można zdefiniować jako np. co 5 sekund lub za pomocą wzorca, czyli np. 'każdy piątek 18:00'.
Można w ten sposób wysyłać użytkownikom co miesiąc jakieś związane z jego aktywnością raporty.
Co trzeba zrobić, żeby użyć Quartz-a w swojej aplikacji? Niewiele.
1. Ściągamy Quartza 1.6 ze strony
2. Dodajemy go sobie do zbioru bibliotek projektu. U mnie było to określone w pliku lib.properties, w katalogu z bibliotekami.
Plik quartz-all-1.6.0.jar skopiowałem do \lib\quartz-1.6.0
a do lib.properties dodałem
quartz.version=1.6.0
quartz.dir=${lib.dir}/quartz-${quartz.version}
quartz.jar=${quartz.dir}/quartz-all-${quartz.version}.jar
3. Jeżeli mamy w projekcie zintegrowanego Springa 2.0, to pozostaje:
3a. utworzyć plik konfiguracyjny applicationContext-quartz.xml i zapisać go w katalogu WEB-INF.

U mnie wygląda następująco:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="outdatetProjectsMailSender" class="pl.unizeto.unitrack.quartz.OutdatedProjectsMailSender">
<property name="userManager"><ref bean="userManager"/></property>
<property name="userTaskManager"><ref bean="userTaskManager"/></property>
</bean>


<bean id="dummyJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject"><ref bean="outdatetProjectsMailSender"/></property>
<property name="targetMethod"><value>sendEmails</value></property>
</bean>


<bean id="dummyCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<ref bean="dummyJobDetail"/>
</property>
<property name="cronExpression">
<value>0/10 * * * * ?</value>
</property>
</bean>


<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="autoStartup" value="true"/>
<property name="waitForJobsToCompleteOnShutdown" value="true"/>
<property name="quartzProperties">
<props>
<!-- Plugins -->
<prop key="org.quartz.plugin.shutdownhook.class">
org.quartz.plugins.management.ShutdownHookPlugin
</prop>
<prop key="org.quartz.plugin.shutdownhook.cleanShutdown">true</prop>
</props>
</property>
<property name="triggers">
<list>
<ref bean="dummyCronTrigger"/>
</list>
</property>
</bean>

</beans>


Co to wszystko znaczy? Ciąg dalszy w następnym poście!