Modyfikatory final i abstract w klasach w Javie

Modyfikator abstract

Modyfikator abstract występujący przy deklaracji klasie oznacza, że mamy do czynienia z definicją, która jest nie kompletna lub też powinna być za taką uważana. Tylko klasa tak oznaczona może zawierać metody, które nie posiadają implementacji. Dana klasa ma metody abstrakcyjne, jeżeli:

  • w klasie jest umieszczona jakakolwiek metoda oznaczona jako abstract
  • jakakolwiek klasa nadrzędna posiada metody abstrakcyjne, które nie zostają implementowane
  • klasa dziedziczy pośrednio lub bezpośrednio interfejs i nie ma implementuje wszystkich jego metod

Klasa abstrakcyjną jest używana w celu uogólnienia zbioru innych klas (zawiera pewne wspólne właściwości tych klas). Może także część tych właściwości definiować, pozwala natomiast zdefiniować interfejs dostępu do innych właściwości, których implementacja musi już nastąpić w którejś klasie potomnej.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
abstract class Figura {

    private int kolor;
   
    public void setKolor(int kolor) {
        this.kolor = kolor;
    }
   
    public abstract void rysuj();
   
}

class Kolo extends Figura {

    private int promien;
   
   
    @Override
    public void rysuj() {
        // implementacja rysowania, przy wykorzystaniu
        // zdefiniowanego wcześniej koloru
    }
}

class Program {
    public static void main(String[] args) {
        Kolo kolo = new Kolo();
       
        Figura kwadrat = new Figura() {
           
            @Override
            public void rysuj() {
                // implementacja rysowania kwadratu
            }
        };
    }
}

Nie można utworzyć obiektu przy wykorzystaniu klasy abstrakcyjnej, jeżeli nie zdefiniuje się wszystkich metod abstrakcyjnych.

Klasa powinna być oznaczona jako abstrakcyjna tylko wtedy, gdy zależy nam na tworzeniu klas potomnych w celu utworzenia pełnej implementacji.

Modyfikator final

Klasa może zostać zdefiniowana jako finalna przy użyciu modyfikatora final. Użycie go przy deklaracji klasy oznacza, że nie można dziedziczyć po danej klasie, jej implementacja jest ostateczna i nie ma możliwości jej modyfikowania.

Przykładami takich klas są np. klasy systemowe: String, Integer czy Long.

1
2
3
4
5
6
7
8
9
10
final class Kwadrat {
   
    int szerokosc;
    int wysokosc;
    int kolor;
   
    public void rysuj() {
       
    }
}

Próba dziedziczenie po podanej klasie spowoduje wygenerowanie komunikatu błędu przez kompilator.

Modyfikatory abstract oraz final wzajemnie się wykluczają (nie można jednocześnie nakazać dziedziczenia oraz zabronić go).

Podsumowanie

Podsumowanie użycia modyfikatorów final i abstract
Modyfikator Użycie w klasie Użycie w interfejsie Użycie w typie enum
abstract Klasa nie finalna może zostać oznaczona jako abstrakcyjna

Klasa która zawiera metody oznaczone jako abstract musi zostać oznaczona także jako abstrakcyjna

Nie można utworzyć obiektu bezpośrednio z klasy abstrakcyjnej (chyba że od razu utworzymy implementację metod abstrakcyjnych)

Dozwolone, ale niepotrzebne,
z założenia interfejs jest abstrakcyjny.
Zabronione.
final Tylko klasa nie abstrakcyjna może zostać oznaczona jako ostateczna.

Klasa zawierająca metody oznaczone jako final nie musi być klasą finalną.

Klasa oznaczona jako final nie może posiadać klas potomnych (nie da się jej rozszerzyć).

Zabronione. Zabronione.

Źródła

Tags: , , , ,

Jakiego zarządcę operacji dyskowych wybrać dla maszyn wirtualnych

Dostępni zarządcy kolejkowania operacji I/O

W Linuksie (przynajmniej w RHEL 5) mam do wybory czterech różnych zarządców procesów (będzie po angielsku):

  • Completely Fair Queuing (CFQ)

    CFQ maintains a scalable per-process I/O queue and attempts to distribute the available I/O bandwidth equally among all I/O requests. CFQ is well suited for mid-to-large multi-processor systems and for systems which require balanced I/O performance over multiple LUNs and I/O controllers.

  • Noop

    The NOOP scheduler is a simple FIFO queue and uses the minimal amount of CPU/instructions per I/O to accomplish the basic merging and sorting functionality to complete the I/O. It assumes performance of the I/O has been or will be optimized at the block device (memory-disk) or with an intelligent HBA or externally attached controller.

  • Deadline

    The Deadline elevator uses a deadline algorithm to minimize I/O latency for a given I/O request. The scheduler provides near real-time behavior and uses a round robin policy to attempt to be fair among multiple I/O requests and to avoid process starvation. Using five I/O queues, this scheduler will aggressively re-order requests to improve I/O performance.

  • Anticipatory

    The Anticipatory elevator introduces a controlled delay before dispatching the I/O to attempt to aggregate and/or re-order requests improving locality and reducing disk seek operations. This algorithm is intended to optimize systems with small or slow disk subsystems. One artifact of using the AS scheduler can be higher I/O latency.

    Agorytm zarządcy dyskowego anticipatory został usunięty w nowych wersjach jądra Linuksa. Ciągle jednak jest (i będzie dostępny) w wersji RHEL 5, która zawiera jądro w wersji 2.6.18.

Można to sprawdzić wydając poleceni:

# cat /sys/block/URZADZENIE/queue/scheduler
noop anticipatory deadline [cfq]

Aktualnie wybrany zarządca jest podany w nawiasach kwadratowych.

Zarządca kolejki I/O dla komputera hosta

W większości przypadków najlepsze efekty osiągnie się korzystając z aglgorytmu cfq. Pracuje on równie dobrze przy praktycznie wszelkich obciążeniach. Jeżeli natomiast jest ważniejsze zminimalizowanie opóźnień I/O kosztem ogólnej przepustowości, być może warto rozszerzyć algorytm deadline.

Zarządca kolejki I/O dla gościa

W przypadku systemów wirtualizowanych sytuacja nie jest już taka prosta. W dużej części przypadków opłacalne może być ustawienie zarządcy kolejki I/O jako noop. Jest to spowodowane tym, że nie ma potrzeby kolejkowania zapisów w dwóch warstwach, raz na systemie gościa a drugi raz na systemie gospodarza. Lepiej jest, gdy to gospodarz decyduje kiedy i jak zapisać czy odczytać dane z dysków. To system hosta ma informacje o wszystkich operacjach dyskowych ze wszystkich maszyn oraz posiada informacje o fizycznej charakterystyce dysków twardych.

Istnieją wyjątki od tej zasady wtedy, gdy system gości uzyskują dostęp do dysków poprzez protokół iSCSI lub też mają podłączone bezpośrednio urządzenie fizyczne. Wtedy powinny samodzielnie zarządzać kolejką I/O.

Konfiguracja domyślnego algorytmu kolejkowania

Zmiana algorytmu kolejkowania I/O w trakcie pracy systemu

Zmianę dokonujemy przy użyciu polecenia echo:

# cat /sys/block/URZADZENIE/queue/scheduler
noop anticipatory deadline [cfq]
# echo 'noop' > /sys/block/URZADZENIE/queue/scheduler
# cat /sys/block/URZADZENIE/queue/scheduler
[noop] anticipatory deadline cfq

Nowy algorytm będzie używany od razu, zmiana ta nie przetrwa restartu maszyny. Natomiast umożliwia wprowadzenie innego sposobu kolejkowania dla różnych urządzeń.

Aby zapewnić wprowadzenie tych zmian po restarcie maszyny, można dodać odpowiedni wpis do pliku /etc/rc.local

# echo "echo 'noop' > /sys/block/URZADZENIE/queue/scheduler" >> /etc/rc.local

Zmiana domyślnego algorytmu kolejkowania I/O

Zmiana domyślnego algorytmu kolejkowania I/O dla systemu Linuks polega na przekazania odpowiedniego parametru do jądra. Przypisujemy wartośc parametrowi elevator nazwę domyślnego algorytmu kolejkowania: noop, anticipatory, deadline oraz cfq.

Przykładowy wpis z pliku /boot/grub/grub.conf:

34
35
36
37
title Red Hat Enterprise Linux Server (2.6.18-8.el5)
root     (hd0,0)
kernel  /vmlinuz-2.6.18-8.el5 ro root=/dev/vg0/lv0 elevator=noop
initrd   /initrd-2.6.18-8.el5.img

Opis, w jaki sposób można modyfikować konfigurację GRUBa zarówno w dystrybucji RedHat jak i Debian można znaleźć we wpisie Konfiguracja dostępu do maszyny wirtualnej przy użyciu polecenia virsh lub xm.

Źródła

Tags: , , , , , , ,

Zdalny dostępu do sieci wewnętrznej przy użyciu protokołu SSH

Zdarza się, że trzeba zalogować się do serwera stojącego za firewallem, do którego nie mamy bezpośredniego dostępu (przynajmniej przy użyciu protokołu SSH).

Jeżeli zapora ogniowa jest oparta

  • firewall jest system opartym o Linuksa, na którym możemy zalogować się przy użyciu SSH
  • mamy możliwość skorzystania z uwierzytelnienia przy użyciu kluczy na oba serwery (nie jest to obligatoryjne, ale nie będzie potrzeby dwukrotnego wprowadzania hasła

Logowanie poprzez wykonanie polecenia

Jedną z podstawowych możliwości aplikacji ssh jest możliwość wykonania komendy na zdalnej maszynie oraz zwrócenie jej wyniku działania. Najprostsza demonstracja:

lukasz@karamba:~$ ssh login@firewall ls -l mysql*
-rw-r--r-- 1 lukasz lukasz 8640154 2008-10-21 04:06 mysql-connector-java-5.1.7.tar.gz

Można to wykorzystać i zamiast polecenia ls wywołać polecenie ssh i połączyć się ze zdalną maszyną:

lukasz@karamba:~$ ssh -t login@firewall 'ssh login@produkcja'

Należy zwrócić uwagę na przełącznik użycie przełącznika -t. Nakazuje on utworzyć terminal na maszynie firewall. Bez tej opcji połączenie będzie działać, ale nie zostanie pokazany np. standardowy znak zachęty.

O czym należy pamiętać:

  • jeżeli korzystamy z uwierzytelniania opartego o klucze, to nasz klucz publiczny musi być zainstalowany na maszynie firewall, oraz klucz publiczny z maszyny firewall musi być zainstalowany na maszynie produkcja, w przeciwnym wypadku będzie trzeba podać hasła
  • niestety sposób ten nie jest kompatybilny z poleceniami scp czy też rsync, aby przekopiować plik z maszyny lokalnej na produkcja należy to wykonać dwuetapowo za pośrednictwem maszyny firewall (w przypadku polecenia rsync da się to ograniczenia ominąć, ale nie jest to już takie oczywiste)

Konfiguracja dyrektywy ProxyCommand

Drugą metodą jest poinformowanie aplikacji ssh, że do połączenia z daną maszyną musi użyć maszyny pośredniczącej w komunikacji.

Należy utworzyć plik (lub zmodyfikować instniejący) ~/.ssh/config:

1
2
Host produkcja
        ProxyCommand ssh login@firewall nc -q0 %h %p 2> /dev/null

Parametr Host (linia 1) wskazuje jakiej maszyny będą dotyczyła konfiguracja. Należy wprowadzić taką nazwę, która będzie użyta podczas łączenia z maszyną wewnątrz sieci. Dyrektywa ProxyCommand (linia 2) informuje aplikację ssh o tym, że należy połączyć się z maszyną firewall i uruchomić polecenie nc.

Po wprowadzeniu tych zmian, można zainicjować połączenie z serwerem produkcja

ssh login@produkcja

Jeżeli używamy uwierzytelniania opartego o klucze połączenie nastąpi automatycznie, w przeciwnym wypadku będzie trzeba podać hasła dostępu do obu serwerów.

O czym należy pamiętać:

  • jeżeli używamy uwierzytelnienia opartego o klucze, to zarówno na maszynie firewall jak i produkcja należy zainstalować klucz z naszego lokalnego systemu (inaczej niż w przypadku pierwszego sposobu)
  • sposób ten jest przezroczysty zarówno dla polecenia scp, rsync czy też innych korzystających ze standardowego klienta ssh, można bezpośrednio kopiować pliki pomiędzy systemami, serwer pośredniczący będzie obsłużony dla nas całkowicie przezroczyście

Źródła

Tags: ,

Użycie serwera proxy przy pomocy polecenia tsocks

W sieciach intranetowych bardzo często nie mamy możliwości łączenia się z systemami udostępniającymi swoje usługi na niestandardowych portach. Przykładami takich usług może być:

  • radio internetowe
  • repozytorium kodu źródłowego (np. udostępnianie przez CVS)
  • zablokowany dostęp do portów SMTP czy POP3
  • i tak dalej, wymieniać można długo.

Jeżeli jednak mamy możliwość wykonywania połączeń przy użyciu SSH, jesteśmy w stanie otworzyć odpowiedni tunel, który umożliwi nam przekierowanie takiego połączenia poprzez niego i ominięcie zabezpieczeń.

Co jednak, jeżeli wybranej przez nas aplikacji nie można skonfigurować tak, aby używała do pracy tunelu? Jeżeli nie chcemy zmieniać konfiguracji całego systemu, tak aby korzystał z tunelu?

Ja miałem taki problem przy próbie połączenia się ze stacjami radiowymi przy użyciu aplikacji Rhythmbox. Chciałem aby ona łączyła się z każdą stacją radiową, a nie znalazłem możliwości konfiguracji połączania przy użyciu serwera proxy czy też tunelu.

Rozwiązaniem tego problemu jest użycie aplikacji tsocks, umożliwi nam przekierowanie połączeń przez utworzony tunel SSH.

Jak działa biblioteka tsocks?

Najprościej mówiąc, tsocks jest biblioteką, która przechwytuje połączenia z podanej aplikacji i przesyła je dalej wykorzystując serwer proxy typu SOCKS.

Aby biblioteka zadziałała poprawnie, należy ustawić odpowiedni zmienną środowiskową LD_PRELOAD, tak aby wskazywała na bibliotekę libtsocks.so. Spowoduje to jej wczytanie zanim jeszcze zostaną wczytane pozostałem biblioteki związane z aplikacją oraz to właśnie funkcje z niej zostaną użyte podczas łączenia.

export LD_PRELOAD=/lib/libtsocks.so

Oczywiście nie musimy tego robić ręcznie, pomocny będzie odpowiedni skrypt o nazwie tsocks napisany w bashu.

Konfiguracja tsocks

Aby biblioteka tsocks zadziałała poprawnie, należy przygotować odpowiedni plik konfiguracyjny, który będzie zawierał informacje potrzebne do przekierowania połączenia.

Plik konfiguracyjny o nazwie .tsocks.conf powinien znajdować się w katalogu domowym użytkownika. Plik ten w najprostszej formie zawiera tylko definicję serwera SOCKS oraz sieci lokalnych, z którymi należy łączyć się bezpośrednio. Dokładne informacje o formacie tego pliku i wszystkich parametrach można znaleźć na stronie MAN tsocks.conf(5). Przykładowy plik konfiguracyjny:

1
2
3
4
server = 127.0.0.1
server_port = 8075
server_type = 5
local = 192.168.1.0/255.255.255.0

Konfiguracja nakazuje łączyć się z serwerem SOCKS typu 5 (linia 3) nasłuchującym na porcie 8075 (linia 2) naszej lokalnej maszyny (linia 1), czyli połączyć się z tunelem stworzonym przy użyciu polecenia ssh. Połączenie z siecią lokalną 192.168.1.0/24 (linia 4) będę się odbywały bezpośrednio.

Zestawienie tunelu

Proste polecenie demonstrujące zestawienie tunelu przy wykorzystaniu aplikacji ssh:

ssh -D 8075 login@host

Jeżeli nie używamy uwierzytelniania opartego o klucze to jeszcze będziemy musieli podać hasło użytkownika na zdalnej maszynie. Po tej operacji klient SSH będzie nasłuchiwał na połączenia na porcie 8075 naszej lokalnej maszyny. Połączenia te zostaną przesłane przez tunel na maszynę zdalną i tam wysłane do serwerów docelowych. Tym sposobem został uruchomiony serwer proxy SOCKS.

Włączenie biblioteki tsocks

Ostatnim krokiem jest uruchomienie aplikacji, która ma korzystać w przezroczysty sposób z serwera SOCKS. Są dostępne trzy możliwości, przydatne w różnych okolicznościach. Do odpowiedniej konfiguracji systemu zostanie wykorzystany skrypt /usr/bin/tsocks. Dokumentacja do niego jest dostępna na stronie MAN tsocks(1).

Uruchomienie pojedynczej aplikacji

Najprostszą metodą na uruchomienie aplikacji jest użycie konstrukcji:

tsocks nazwa_aplikacji_do_uruchomienia

Spowoduje ustawienie zmiennej środowiskowej LS_PRELOAD i uruchomienie żądanej aplikacji. Aplikacji już powinna automatycznie korzystać z serwera proxy, nie będąc tego świadomą.

Konfiguracja uruchomionej powłoki

W ramach aktualnej powłoki możemy włączyć korzystanie z serwera proxy dla wszystkich aplikacji później uruchamianych. Korzystamy wtedy z polecenia:

$ source tsocks -on

lub też z jego krótkiej formy:

$ . tsocks -on

Spowoduje to odpowiednie ustawienie zmiennej środowiskowej LD_PRELOAD w aktualnej powłoce systemowej.

Wyłączenie serwera proxy następuje po wydaniu komendy:

$ source tsocks -off

lub też:

$ . tsocks -off

Należy zwrócić uwagę na wykorzystanie polecenia source. Jeżeli tego nie zrobimy, powłoka nie zostanie skonfigurowana poprawnie.

Aby sprawdzić czy mamy ustawione przekierowanie połączeń na serwer pośredniczący, używamy instrukcji:

$ tsocks -show
LD_PRELOAD="/usr/lib/libtsocks.so"

W wyniku jej wykonania zostania pokazana zawartość zmiennej środowiskowej LD_PRELOAD. Jeżeli zawiera ona ścieżkę do biblioteki libtsocks.so oznacza to, że mamy skonfigurowane połączenie z serwerem proxy.

Utworzenie nowej powłoki

Ostatnią możliwością jest utworzenie od razu odpowiednio skonfigurowanej nowej powłoki. Można to zrobić wywołując po prostu polecenie tsocks bez żadnych parametrów:

$ tsocks
$ tsocks -show
LD_PRELOAD="/usr/lib/libtsocks.so"

Wszystkie wywoływane aplikacje z tej powłoki będą łączyły się przy użyciu serwera proxy. Powłokę można opuścić wydając polecenie exit.

Źródła

Tags: , , , ,

Migracja Joomli z wersji 1.0 do wersji 1.5

Opis procesu migracji portalu internetowego z postawionego na Joomli 1.0.14 do wersji 1.5.15.

Kopia bazy danych

Wykonanie kopii bazy danych nie jest konieczne, ponieważ nowa wersja będzie korzystała z czystej bazy danych, ale dobrym zwyczajem jest robienie kopii.

mysqldump www > joomla.sql

Migracja danych

  1. Zainstalować w Joomli 1.0 komponent Migrator.
  2. Utworzyć plik XML przy użyciu komponentu Migrator.
  3. Pobrać wygenerowany plik SQL.
  4. Dokonać konwersji pliku SQL z formatu LATIN2 na UTF-8:
    iconv -f latin2 -t utf8 -o www_20100211_121246_utf8.sql www_20100211_121246.sql

W tym momencie dysponujemy już kopią dynamicznych stron oraz zapisanymi informacjami o użytkownikach. Skopiowany plik SQL będzie potrzebny w celu wczytania informacji do nowej instancji Joomli.

Instalacja Joomli 1.5

  1. Skopiować źródła PHP w odpowiednie miejsce, skonfigurować serwer WWW.
  2. Utworzyć nową bazę danych oraz przydzielić uprawnienia do bazy danych użytkownikowi.
    CREATE  DATABASE joomla DEFAULT CHARACTER SET utf8;
    GRANT ALL PRIVILEGES ON `joomla` . * TO 'joomla_user'@'localhost';
  3. Rozpocząć instalację Joomli. W momencie tworzenia serwisu należy wczytać przygotowany wcześniej plik SQL, podaniu prefiksu do tabel (domyślnie było jos_) oraz zaznaczeniu pola informującego, że przeprowadzany jest import danych z wersji 1.0.
  4. Koniec, jeżeli nie wystąpiły błędy to migracja zakończona sukcesem.

Potencjalne problemy

Błąd SQL spowodowany brakiem niektórych tabel.

Błąd taki wystąpił w sytuacji, gdy nie został podany prefiks jos_ dla tabel przy imporcie danych.

Przydatne linki

Tags: , ,