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!

wtorek, 30 października 2007

Eclipse 3.3 vs NetBeans 6.0 beta 2

Od ponad roku używam Eclipse do małych, złożonych z kilku (nastu) klas projektów. Do tej pory pracowałem w Visual C++ 6.0 z plugin-em WholeTomato oraz BCB 5 i 6. To, co mi się do tej pory rzuciło w oczy to między innymi błyskawiczna kompilacja w porównaniu z tymi kompilatorami C++, szybka i sensowna podpowiedź kontekstowa w edytorze, fantastyczne podpowiedzi przy błędach typu 'jaki błąd tutaj popełniłeś i jak go można poprawić' - Ctrl + 1.
Muszę przyznać, że dzięki Eclipse polubiłem programowanie w Javie.
Kilka dni temu zauważyłem że pojawiła się beta 2 konkurencyjnego środowiska, NetBeans.
Czy jest lepsze od Eclipse? Ponieważ nigdy wcześniej go nie używałem, na świeżo w miarę mojego wgłębiania się w nie spróbuję odpowiedzieć na to pytanie. Lub chociaż wyrobić sobie jakieś zdanie :)
Jeżeli już mamy JDK, to wystarczy ściągnąć 20 MB instalkę, żeby móc cieszyć się wersję IDE dla Java SE. Dla EE instalka ma 95 MB ze względu na dołączenie Glassfisha, Tomcata i związanych z tym funkcjonalności.
Teraz biorę się za pierwszy próbny projekt :)

A tu mam tutorial, który pewnie również przejdę:
http://youtube.com/watch?v=MC2DiUibMoQ

poniedziałek, 29 października 2007

Shutdown Hook

Jak się okazuje, można w miarę łatwo przechwycić w Javie zdarzenie zamykania maszyny wirtualnej. Wystarczy dodać w taki sposób obiekt dziedziczący z klasy Thread (u mnie nazywa się po prostu ShutdownThread):

Runtime.getRuntime().addShutdownHook(new ShutdownThread());

To co ma być zrobione zamieszczamy w metodzie public void run().
Tak więc nasz obiekt jest wątkiem, który jest zainicjalizowany przez konstruktor, ale nie wywołano start();

czwartek, 20 września 2007

SSL w Tomcat 5.5 i wyżej

Jak 'w miarę' szybko włączyć SSL-a w Tomcat-cie 5.5?

1. Potrzebujemy certyfikatu klucza publicznego i klucza prywatnego dla naszego serwera, można uzyskać darmowy np. od Thawte na 30-90 dni lub generujemy go sobie na próbę sami przy pomocy keytool z Java JDK.
Należy pamiętać, że CN w nazwie certyfikatu (Common Name) musi odpowiadać adresowi IP lub nazwie naszego serwera.
Docelowo dla publicznego serwera na którym mamy nasz będziemy musieli sobie go kupić, ale nie jest to duży wydatek.
Teraz, jeżeli otrzymaliśmy od CA plik P12 to lecimy do punktu 2.

2 a)
Jeżeli nie posiadamy certyfikatu i klucza prywatnego w postaci pliku P12/PFX, ale mamy klucz prywatny (np. server.key) i związany z nim certyfikat klucza publicznego (server.crt) to musimy z nich zrobić PFX-a.
Robimy to kopiując zawartość klucza i certyfikatu do jednego pliku w notatniku lub innym edytorze tekstowym i zapisujemy do pliku server.pem.
Teraz wystarczy jedna linijka polecenia za pomocą OpenSSLa:
openssl pkcs12 -export -in server.pem -out server.p12
i podajemy hasło do naszego pliku pfx, np. 'password' :)

2. Kopiujemy server.p12 do CATALINA_HOME, czyli np. c:\Program Files\Apache Software Foundation\Tomcat 5.5

3. Modyfikujemy plik CATALINA_HOME\conf\server.xml,
dodajemy nowy konektor za innym tagiem o tej samej nazwie:
< port="443" protocol="HTTP/1.1" maxthreads="150" keystorefile="server.p12" keystorepass="password" keystoretype="PKCS12" sslenabled="true" scheme="https" secure="true" clientauth="false" sslprotocol="SSL">

Jeżeli chcemy, żeby tylko za pośrednictwem SSL-a można było łączyć się z serwerem, to musimy jeszcze zakomentować tag z drugim konektorem, do portu 8080.

4. Restartujemy serwer, i próbujemy połączyć się z nim za pośrednictwem https, np. u mnie to jest taki adres: https://192.168.128.123/aplikacja/login.jsp

Jeżeli wszystko dobrze zrobiliśmy, to już możemy używać bezpiecznego połączenia z serwerem!

SCJP

We wtorek 18. zostałem Javczakiem. Z certyfikatem od Suna.
Konkretnie to zdałem egzamin "Sun Certified Java Programmer" 310-055 i strasznie się z tego cieszę :)
Zabierałem się do tego od wiosny, ale zawsze miałem wrażenia że za mało umiem.