sobota, września 26, 2009

Jak uaktywnia się skalowanie okna TCP



W przypadku Axis-a można to rozwiązać tak:

System.setProperty("tcp.window.size", "64000");
AxisProperties.setProperty("axis.socketFactory", "CustomSocketFactory");

Czasy WebService'u dla rozmiaru okna:

1460 (RWIN=MSS :) => 21860 ms
5000, 7000, 17000, 33000, 64000 => 4500-6500 ms

TCP Window Scaling

Diagnostyka i konfiguracja. Po drodze może być stary Cisco IOS Firewall obcinający pakiety spoza okna (którego rozmiar jest w rzeczywistości przeskalowany przez 2^wscale)...

poniedziałek, września 14, 2009

Tweakowanie systemu Windows

... na podstawie oryginalnej dokumentacji od MS.

piątek, września 11, 2009

Prstat

27109 adinstan  469M  323M cpu1    30    0 209:37:17  35% bwengine/64
27109 adinstan 469M 323M cpu17 20 0 209:37:45 35% bwengine/64
27109 adinstan 469M 323M cpu16 20 0 209:38:14 35% bwengine/64
27109 adinstan 469M 323M cpu17 20 0 209:38:56 35% bwengine/64
27109 adinstan 469M 323M cpu18 20 0 209:39:10 35% bwengine/64
27109 adinstan 469M 323M cpu0 10 0 209:39:24 35% bwengine/64
27109 adinstan 469M 323M cpu2 10 0 209:39:38 35% bwengine/64
27109 adinstan 469M 323M cpu19 10 0 209:40:07 35% bwengine/64
Proces skacze po procesorach. Można go dowiązać narzędziami psrset+pbind, co powinno zmniejszyć opóźnienia (ważna rzecz dla np. aplikacji RT).

wtorek, września 08, 2009

Yet another firewall issue



Pod koniec wywołania WebService'u ginie segment TCP; warstwa transportowa ciągle próbuje dokończyć transmisję, co widać jako wiszenie WebService'u. Co ciekawe, w takim przypadku w kliencie .NET ustawienie timeout-u nic nie daje i aplikacja kliencka będzie cała wisieć.

W trybie debugowania pojawia się ContextSwitchDeadlockException: The CLR has been unable to transition from COM context 0x21def80 to COM context 0x21df1d0 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
netsh int tcp set global autotuninglevel=disabled
DefaultTTL=128, SackOpts=0

sobota, września 05, 2009

Software'owy RAID w W2K8

Mirror partycji systemowej możemy stworzyć paroma kliknięciami bez restartu. Do boot menu dodana zostanie pozycja umożliwiająca odpalenie systemu z drugiego dysku. Wszystko dużo łatwiejsze i szybsze niż w Linuksie i Solarisie. Mój ulubiony layout: RAID1 + RAID0.


czwartek, sierpnia 20, 2009

Transaction timeout na WLS a QueryTimeout na JDBC

Przekroczenie czasu wykonywania się transakcji i jej rollback nie gwarantuje, że w tym samym momencie przerwane zostanie zapytanie JDBC. Weblogic może rzucić wyjątek TimedOutException, a Statement JDBC będzie się nadal wykonywać. Dlatego należy pamiętać o Statement.setQueryTimeout(). Uwaga: nie wszystkie bazy to obsługują.

DbDiff na replice read-only

Założenie: z produkcyjnej bazy danych online generowana jest codziennie replika read-only. Chcemy w jakiś sposób generować różnice pomiędzy stanem z dnia obecnego a stanem z dnia poprzedniego. Tabelki zawierają od kilkuset tysięcy do paru milionów rekordów. Projekt nie jest priorytetowy i nie chcemy na niego wydawać pieniędzy.

Rozwiązanie: Tworzymy bazę przejściową z tabelkami CURRENT_* i PREVIOUS_*. Na początku transakcyjnej operacji kopiujemy wszystkie CURRENT_* do PREVIOUS_*, potem ładujemy aktualny stan bazy read-only do CURRENT_* i liczymy różnicę (select minus select). Baza przejściowa ma do dyspozycji 1500MB pamięci, program do generowania różnicy 768MB.

Warunki brzegowe: Tabelki źródłowe po zserializowaniu do plików mają > 300MB. Dell + Intel Core 2 Quad 2.4 GHz + 3GB RAM + NT5.

Wyniki:
Czas operacji na bazie:
Apache Derby: 31 minut (bez select into table)
Oracle XE: 12 minut (20 minut bez create table as select)
MSSQL 2005 Express: 16 minut (24 min bez select into from).
PostgreSQL: nie da się (transakcje nie działają tak jak trzeba)
MySQL: nie da się (brak operatora minus/except)

Kto tworzy Linuksa

Sporo ludzi. Na pierwszym miejscu osoby prywatne (21.1% zmian w kodzie), na drugim RedHat (12.0%), potem IBM (6.3%), Novell (6.1%), Intel (6.0%), Oracle (3.1%), Parallels - producent narzędzi do wirtualizacji (1.7%), Fujitsu (1.5%), SGI (1.2%), Sun i HP (1.0%), Freescale, Marvel i MontaVista (0.9%), AMD, Nokia, Google, Atheros (0.8%). A firmy Canonical w zasadzie nie widać. Ubuntu ssie...

środa, sierpnia 19, 2009

Metro Sun-a nie działa z Sharepointem MS

Na końcu metody getElementPropertyAccessor w klasie JAXBContextImpl z pakietu com.sun.xml.bind.v2.runtime nie należy rzucać wyjątku tylko zwrócić dodatkowy Accessor, który bierze pod uwagę, że klasy MS mogą mieć nazwy zaczynające się od Get i Set...
public GetSetAccessor(Class wrapperBean, String localName)
throws JAXBException
{
try {
String javaFieldName = Character.toLowerCase(
localName.charAt(0)) + localName.substring(1);
wrapperBean.getDeclaredField(javaFieldName);
}
catch (Exception e) {
throw new JAXBException("No access to field "+
localName + " of " + wrapperBean+": "+e.toString());
}
String fieldInMethod = Character.toUpperCase(
localName.charAt(0)) + localName.substring(1);

String setterName = "set"+fieldInMethod;
String getterName = "get"+fieldInMethod;

for (Method m : wrapperBean.getMethods()) {
if (m.getName().equals(setterName) &&
m.getParameterTypes().length==1) {
setter = m;
}
else if (m.getName().equals(getterName) &&
m.getParameterTypes().length==0) {
getter = m;
}
}
}
No i gdzie to interoperability out of box?...

piątek, sierpnia 14, 2009

Plugin do Jiry wywołujący WebService Sharepoint-a

Jira używana jest do prowadzenia zgłoszeń, a Sharepoint do przechowywania dokumentów. Plugin typu "post-function" tworzy stronę Sharepointa dla danego zgłoszenia. Klient WebService'u został wygenerowany Metrem (z założenia Metro umie rozmawiać z WS Microsoftu wymagającymi autoryzacji, z ISA Serverem pomiędzy). Pliki źródłowe klienta się nie kompilują i mają błąd tworzenia URL-a dla WSDL-a umieszczonego w pliku jar:
baseUrl = Clazz.class.getResource(".");
url = new URL(baseURL, "clazz.wsdl");
należy zamienić na:
url = Clazz.class.getResource("clazz.wsdl");



Dla CreateSite konieczne jest wykonanie: stsadm -o addpath http://site -type wildcardinclusion.
Dla CreateWorkspace możemy użyć własnego template'u.

środa, sierpnia 12, 2009

Jak wyjąć zaszyfrowane hasła z konfiguracji WebLogic'a

new weblogic.security.internal.encryption.ClearOrEncryptedService(
SerializedSystemIni.getEncryptionService(
"/home/weblogic/bea/domains/wls0"
)
).decrypt("{3DES}1234abcd==");

wtorek, sierpnia 11, 2009

Zużycie procesora przez maszyny wirtualne w trybie idle


Windows 2008 Sever 64-bit, średnio 23%


RHEL 5.3 64-bit, średnio 4%


OpenSUSE 11.1 64-bit, średnio 0.5%.

Na wszystkich trzech maszynach są nieużywane środowiska WebMethods.

A całościowy load dla ośmiordzeniowej maszyny wygląda tak:
5:34pm up 63 days 1:49, 1 user, load average: 2.73, 5.68, 6.39

niedziela, sierpnia 09, 2009

KDE 4.3 w Fedorze 11

Do /etc/yum.repos.d wrzucamy kde.repo z włączonym repozytorium testing. Następnie wystarczy zrobić yum update.



Efekty GUI chodzą przyzwoicie na GF9100M (trzeba w /etc/modules.d/blacklist.conf dodać nouveau, używam sterownika nvidia). Przeglądanie folderów w plazmoidzie jest sensownie rozwiązane.

piątek, lipca 24, 2009

Eksport bookmarków

Breakable Oracle
PoznajFakty
Nie należy krzyczeć na serwer
Cytaty z House'a
Generator newsów
Proxy detector

czwartek, lipca 23, 2009

NTLM Jira workaround

REGEDIT4

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings]
"ProxyOverride"="jira;"
"DisableNTLMPreauth=dword:00000001

IE czasami gubi się w trakcie handshake'u NTLM, zwłaszcza kiedy dostaje żądanie autoryzacji od razu przy ładowaniu URL-a, a nie po HTTP 304 czy wybraniu linka.

wtorek, lipca 21, 2009

Pogoda

Widok z góry

niedziela, lipca 19, 2009

Safari najszybsze

Futuremark Peacekeeper


Wymagania dla Developera Systemów IT

  • Programowanie Java + Web Development
    • J2EE
      • Servlety
      • JSP
      • EJB
      • WS
      • JMS
    • UI
      • Swing
      • Qt Jambi
      • DHTML
      • CSS
      • Paint Shop Pro/GIMP
    • Serwery aplikacyjne + infrastruktura
      • Tomcat
      • WebLogic
      • Apache + mod_proxy
      • WebMethods lub inna platforma integracyjna
    • Narzędzia
      • Eclipse
      • Grails
  • Programowanie C/C++/C#
    • UNIX
    • POSIX
    • WinAPI
    • C++ Builder
    • .NET
  • Znajomość protokołów i formatów
    • TCP/IP
    • HTML + typowe nagłówki
    • POP3
    • SMTP
    • NTLM
    • AT (modem)
    • XML
      • XSLT
      • XSD
      • WSDL
    • UML
  • Programowanie shellowe UNIX
    • Bash, sed, awk
  • Reverse Engineering i diagnozowanie problemów
    • Dekompilacja, JAD, wzorzec projektowy wrapper/proxy, podmiana klas
    • Strace, objdump
    • Diagnostyka JMS-a za pomocą narzędzia Hermes
    • Profilowanie aplikacji (YKP)
    • Tuningowanie maszyny wirtualnej (w tym GC) Sun JVM, BEA JRockit
    • Serwery Dell
  • Bazy danych (dewelopment, częsciowo administracja)
    • MSSQL
    • Oracle
    • PostgreSQL
  • Administracja systemami operacyjnymi i narzędziami do pracy grupowej
    • Windows 2003/2008
    • RedHat/Fedora
    • SuSE
    • VMware
    • Subversion
    • Wiki
  • Zagadnienia koncepcyjne
    • Inżynieria oprogramowania
    • Wzorce projektowe
    • Wzorce projektowe EAI
    • SOA
    • Wzorce projektowe SOA
    • BPM
    • Testowanie aplikacji
    • HCI, projektowanie UI
    • Balancing, fail-over
    • System operacyjny UNIX (planista, zarządzanie pamięcią, libc)
    • Zwinne podejścia do wytwarzania oprogramowania (eXtreme Programming, Scrum)
    • Bezpieczeństwo
  • Znajomość bibliotek, technologii, technik, narzędzi, itp.
    • Xerces, DOM
    • XStream
    • XMLSpy
    • JUnit
    • Selenium IDE
    • Pobieżna znajomość silników przeglądarek WWW (IE, Firefox, KHTML, Opera)
    • Statystyka matematyczna + StatGraphics lub R
Bold - must have
Not bold - would be nice

sobota, lipca 18, 2009

TiltOS

System zarządzania pakietami dla Haiku. Jest Midnight Commander!

Apple introduces closures!

MacOS X Snow Leopard będzie miał planistę wątków opracowanego specjalnie dla procesorów wielordzeniowych. Co ciekawe, programista będzie korzystał z Grand Central Dispatch, poprzez closures.

Blocks

Blocks are a simple extension to C (as well as Objective-C and C++) that make it easy
for you to define self-contained units of work. A block in code is denoted by a caret at
the beginning of a function. For example, you could declare a block and assign it to x
by writing:
x = ^{ printf("hello world\n"); }
This turns the variable x into a way of calling the function so
that calling x( ); in the code would print the words hello world.

Android



Cały pulpit działa w fbdev-ie (czysty framebuffer), bez X-ów. Patrząc później na listę procesów można dojść do wniosku, że Android koncepcyjnie bardzo przypomina BeOS-a.





Przeglądanie dużych stron na małym ekranie jest bardzo fajne. W domyślnym widoku widzimy kawałek strony w skali 1:1 mieszczący się na małym ekranie. Po kliknięciu ikony pojawiającej się w dolnym prawy rogu podczas przewijania zawartości strony, dostajemy widok pomniejszonej strony z ramką przedstawiającą wycinek w skali 1:1. Przestajemy ruszać ramką - widzimy standardowej wielkości kawałek strony. Oprócz tego mamy dwie ikony: zoom in, zoom out; możemy ruchem kursora przesuwać zawartość (tak jak w Google Maps).




Sprawdźmy jakiej przeglądarki używamy (na stronie webmaster.helion.pl Pawła Wimmera ze skryptami JS): Mobile Safari. Hmm... Ani Chrome ani Chromium, ale do tych potrzebne byłoby GTK i Xy, których w Androidzie nie ma!



Odpalmy terminal i zobaczmy w BusyBoksie, co jest pod spodem.



Linux 2.6.27, obcięty i raczej bardzo statyczny (niewielka liczba modułów w /lib/modules).



Własny init, tutaj przypomniał mi się BeOS i jego Kity.



Tak wyglądają aplikacje - zmodyfikowana androidowa Java. Sun pewnie nie jest ucieszony.



W GUI mam sieć, a w konsoli nic z tego, wszystko poblokowane.



Patrząc na ps, ma się wrażenie oglądania systemu z mikrojądrem i serwisami. BeOS was cool.

Co jeszcze należy dodać? Cały system korzysta, ze statycznego obrazu skompresowanego squashfs-em, na to nakładka read-write aufs. Ustawienia i artefakty użytkownika zapisywane na karcie SD. Na netbooka system będzie nadawał się doskonale.

sobota, lipca 11, 2009

Spalony kontroler klawiatury i już po laptopie

Laptop się nie włącza, ale świeci się dioda baterii. Rozbieramy obudowę i wyjmujemy płytę główną.



Po przyłożeniu baterii okazuje się, że jeden układ parzy - PC87541V-VTC (NT618G), czyli mamy zwarcie. Niestety układ ma za dużo nóżek i są one za małe, żeby w domowych warunkach go wylutować. Płyta główna jest do wyrzucenia.



A tu zdjęcie GMA945 i Celerona - rozmiary kontrolera grafiki i procesora są zbliżone.

czwartek, lipca 09, 2009

C++ Builder still alive (wersja 2009)

środa, lipca 08, 2009

Duża liczba połączeń w stanie CLOSE_WAIT na Apache'u

W ramach rekomendacji poaudytowych Altkom radzi firmom bezkrytycznie włączać najlepiej wszystkie reguły SmartDefense na firewallu CheckPoint. Gdyby chociaż raz przetestowali to, co proponują, to by wiedzieli, że mogą swoim doradztwem zrobić ludziom bajzel na produkcji.

Zablokowanie połączeń TPC/IP keep-alive realizowane jest w ten sposób, że firewall preparuje pojedyńczy pakiet FIN+ACK, który wysyła do hosta. Host ten liczy, że wyśle ACK-a i dostanie w odpowiedzi FIN+ACK, a po wysłaniu LAST_ACK zamknie połączenie. Tymczasem taka wyminana pakietów nie zachodzi i mamy wiszące połączenia w stanie CLOSE_WAIT. Po pewnym czasie procesy Apache'a strasznie się mnożą, a cały serwis WWW przestaje odpowiadać.

Workaround w httpd.conf:
KeepAlive Off
TimeOut 60

piątek, lipca 03, 2009

SMSGW: mail-sms gateway

Techbase NPE is a device that comes with 180MHz 32-bit ARM processor, 64 MB of RAM, 4MB of writable FLASH memory, SD card reader and Sim600 GSM EDGE modem. Device is handled by Linux 2.6.20 with BusyBox tools, there is JamVM – embedded Java Virtual Machine more or less compatible with Sun JVM 1.4.

Device was chosen to be a part or IT infrastructure monitoring. All alerts are sent to device via SMTP mail protocol and then delivered as a SMS.

Software used for assembling of application:

SMSGW with documentation is avaliable from systest.googlecode.com

To integrate SMSLib I had to port it from Java 1.5 to JamVM 1.4 (note that GNU Classpath doesn't support POSIX extensions to regular expressions), fix SLFJ startup checks and change usage of RXTX to direct way instead of reflection. RXTX used by me didn't have mappings for B115200 and B230400 and I had to look them up in termios.h (file is available in Linux kernel sources), found values should be used in port.setSerialPortParams().

czwartek, czerwca 25, 2009

Workaround na wieszające się serwery Della

Wygląda na to, że serwery Della z 8-mioma rdzeniami Intel Xeon przegrzewają się pod Linuksem. Teoretycznie Xeony mają Thermal Circuit Control, który przy nadmiernym wzroście temperatury powinien spowalniać procesor, ale pod Linuksem nie widać jego działania, widać za to, że serwer wiesza się sprzętowo. Workaround to unikanie niepotrzebnych migracji procesów między rdzeniami, co przy ciągłym (wielodniowym) obciążeniu ~5% załatwia problem:
echo 1 > /sys/devices/system/cpu/sched_mc_power_savings.

piątek, czerwca 19, 2009

Monitoring na sms-a

Kupujemy modem GSM, podłączamy go do linuksowego serwera, stawiamy na serwerze bramkę mail-sms, a potem już tylko:
HOSTNAME=`hostname`
USER=`whoami`
SMTP="10.10.1.25"

function sendmail {
(
sleep 3
echo "HELO $HOSTNAME"
sleep 1
echo "mail from: monitoring@email.com"
sleep 1
echo "rcpt to: smsgw@email.com"
sleep 1
echo "data"
sleep 1
echo "From: monitoring.$USER@email.com"
sleep 1
echo "To: smsgw@email.com"
sleep 1
echo "Subject: $1"
sleep 1
echo ""
sleep 1
echo "$2"
sleep 1
echo "."
sleep 1
echo "quit"
sleep 1
) | telnet $SMTP 25
}

sendmail "$1" "$2"

# ./sendsms "+48602201122" "Brak dzialajacego procesu A dla systemu B"

czwartek, czerwca 18, 2009

Jakim cudem Java ME na komórkach może być szybka?

Procesory ARM miewają natywną obsługę bajtkodu Javy - Jazelle.

Automatyczne testowanie aplikacji webowych

"Przechodzimy" aplikację w Firefoksie wyposażonym w plugin "Live HTTP headers" i kopiujemy dane wysyłane formularzem. Dane te wkleimy potem do linii poleceń wgeta.



Przykładowy skrypt:
WP_URL="http://10.10.1.20:8080/app/AppServlet"
COOKIE="cookie.dat"
WGET_CMD="wget --timeout=15 --keep-session-cookies --save-cookies=$COOKIE --quiet $WP_URL -O -"
> $COOKIE

RUNNING=$(ps uax | grep -c nazwa_skryptu.sh)
[[ $RUNNING -gt 3 ]] && echo "Poprzednie wywolanie skryptu wisi" && exit 1

RES=$($WGET_CMD --post-data="user=jan.kowalski&password=lubieTpsa&action=login" | grep -c "Zalogowany: ")
echo "Test logowania. Wynik: $RES"
RES=$($WGET_CMD --load-cookies=$COOKIE --post-data="action=create-process&action_params=...&state=" | grep -c "Nowy proces")
echo "Zaladowanie procesu. Wynik: $RES"
RES=$($WGET_CMD --load-cookies=$COOKIE --post-data="action=next&action_params=..." | grep -c "Dane zapisano")
echo "Wynik procesu poprawny?: $RES"
RES=$($WGET_CMD --load-cookies=$COOKIE --post-data="action=save-and-close&action_params=..." | grep -c "Zakonczono proces")
echo "Zamkniecie procesu. Wynik: $RES"
RES=$($WGET_CMD --load-cookies=$COOKIE --post-data="action=logout" | grep -c "Wylogowano uzytkownika")
echo "Wylogowanie. Wynik: $RES"

wtorek, czerwca 16, 2009

HostDeny z logów Apache'a

#!/bin/sh
RATE_LIMIT="100"
HOSTS_DENY=".htaccess"
LOG="/home/apache_wp/apache_wp/logs/access_log_443"
DT=$(date +%d/%b/%Y:%k:%M)
PERIODIC_LOG="periodic.log"

cat $LOG | grep "$DT" | grep "SomeServletUrl" | cut -d" " -f1 > $PERIODIC_LOG
echo "### Generated at $DT ###">> $HOSTS_DENY

for ip in $(cat $PERIODIC_LOG | sort -u); do
cnt=$(cat $PERIODIC_LOG | grep -c "$ip");
[[ $cnt -gt $RATE_LIMIT ]] || continue;
echo >> $HOSTS_DENY;
echo "# $ip generated $cnt requests above rate limit $RATE_LIMIT" >> $HOSTS_DENY;
echo "Deny from $ip" >> $HOSTS_DENY;
done;

niedziela, czerwca 14, 2009

OpenESB nightly build

Sun schował je tutaj:
http://download.java.net/jbi/binaries/open-esb-full-install/v2.1/nightly/latest/
http://download.java.net/jbi/binaries/glassfishesb/v2.1/nightly/latest/

[2009-10-11] http://download.java.net/jbi/binaries/installers/single-component/v2.1/nightly/

sobota, czerwca 13, 2009

Upgrade Fedory 10.9x do finalnej 11

W /etc/yum.repos.d wyłączamy fedora-rawhide.repo (Enabled=0), włączamy fedora.repo i fedora-updates.repo oraz wewnątrz tych plików zmieniamy $releasever na 11 i odpalamy yum upgrade.

piątek, czerwca 12, 2009

LicensedCpus.c

Program dedykowany wszystkim dyrektorom IT, którzy nie wiedzą, że software licencjonowany na 2 CPU można uruchamiać na serwerze z 4 CPU.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>
#include <string.h>

int get_num_cpus() {
int cnt = 0;
char *line = NULL;
size_t len = 0;
FILE *fp = fopen("/proc/stat", "r");
if (fp!=NULL) {
while (getline(&line, &len, fp)!=-1) {
if (line!=NULL && strstr(line, "cpu")!=NULL)
cnt++;
}
if (line)
free(line);
fclose(fp);
cnt--;
}
return cnt;
}

int main(int argc, char** argv) {
static cpu_set_t mask;
int user_mask, i=0, max, m=0;

if (argc<3) {
fprintf(stdout, "Usage: %s cpu_mask(int) command(full_path)\n",argv[0]);
exit(0);
}

user_mask = atoi(argv[1]);
max = 1 << (get_num_cpus()-1);
CPU_ZERO(&mask);
for (i=0; i<max; i++) {
if ( (user_mask & (1 << i)) == (1 << i)) {
CPU_SET(i, &mask);
m |= (1<<i);
}
}

if (sched_setaffinity(0, sizeof(mask), &mask)==0) {
fprintf(stdout, "Running %s with mask %d, cpus=%d\n", argv[2], m, max);
return execv(argv[2], argv+2);
}
else {
fprintf(stderr, "Cannot set cpu mask: %s. Effective mask was %d\n", strerror(errno), m);
exit(1);
}
}

sobota, czerwca 06, 2009

Jak GCC dzieli przez 100

mov edx, 600
mov eax, 51EB851Fh ; EAX = 32/100 * 2^32
mul edx
mov eax,edx
shr eax,5 ; EAX = EAX/32

środa, czerwca 03, 2009

Naprawiona biblioteka libIntroscopeRedHatStats.so

Idea poprawki polega na stworzeniu proxy na bibliotekę i własnej implementacji metody getAggregateCPUUsage.

Pozostałe funkcje JNI można prawdopodobnie zaimplementować następująco:

getProcessCPUUsage -> getrusage()
getTotalClockTicks -> clock()
isThreadCpuTimeEnabled -> defined RUSAGE_THREAD
getThreadCpuTime -> getrusage(RUSAGE_THREAD, &usage)

Update: Przepisałem całą bibliotekę, gdyby ktoś chciał binarkę prośba o kontakt.

Memory leak in Wily Introscope

Wygląda na to, że agent Introscope ma wycieki pamięci w natywnym kodzie:
[tomcat@swa158 ~]$ jrcmd 0 print_memusage
18130:
[JRockit] memtrace is collecting data...
[JRockit] *** 0th memory utilization report
(all numbers are in kbytes)
Total mapped ;;;;;;;1192600
; Total in-use ;;;;;;1182252
;; executable ;;;;; 12260
;;; java code ;;;; 7680; 62.6%
;;;; used ;;; 5763; 75.0%
;; shared modules (exec+ro+rw) ;;;;; 4540
;; guards ;;;;; 1056
;; readonly ;;;;; 68
;; rw-memory ;;;;;1177604
;;; Java-heap ;;;; 393216; 33.4%
;;; Stacks ;;;; 22871; 1.9%
;;; Native-memory ;;;; 761516; 64.7%
;;;; java-heap-overhead ;;; 12342
;;;; codegen memory ;;; 904
;;;; classes ;;; 29696; 3.9%
;;;;; method bytecode ;; 2927
;;;;; method structs ;; 3278 (#69939)
;;;;; constantpool ;; 11117
;;;;; classblock ;; 1488
;;;;; class ;; 3060 (#8698)
;;;;; other classdata ;; 4942
;;;;; overhead ;; 280
;;;; threads ;;; 107; 0.0%
;;;; malloc:ed memory ;;; 24265; 3.2%
;;;;; codeinfo ;; 1047
;;;;; codeinfotrees ;; 438
;;;;; exceptiontables ;; 591
;;;;; metainfo/livemaptable ;; 9324
;;;;; codeblock structs ;; 3
;;;;; constants ;; 6
;;;;; livemap global tables ;; 2091
;;;;; callprof cache ;; 0
;;;;; paraminfo ;; 88 (#1284)
;;;;; strings ;; 4991 (#92449)
;;;;; strings(jstring) ;; 0
;;;;; typegraph ;; 1593
;;;;; interface implementor list ;; 48
;;;;; thread contexts ;; 81
;;;;; jar/zip memory ;; 5451
;;;;; native handle memory ;; 39
;;;; unaccounted for memory ;;; 694309; 91.2%;28.61
---------------------!!!

16612:
[JRockit] memtrace is collecting data...
[JRockit] *** 0th memory utilization report
(all numbers are in kbytes)
Total mapped ;;;;;;;1192932
; Total in-use ;;;;;;1181960
;; executable ;;;;; 12004
;;; java code ;;;; 7424; 61.8%
;;;; used ;;; 5796; 78.1%
;; shared modules (exec+ro+rw) ;;;;; 4540
;; guards ;;;;; 1068
;; readonly ;;;;; 68
;; rw-memory ;;;;;1177312
;;; Java-heap ;;;; 393216; 33.4%
;;; Stacks ;;;; 23003; 2.0%
;;; Native-memory ;;;; 761092; 64.6%
;;;; java-heap-overhead ;;; 12342
;;;; codegen memory ;;; 592
;;;; classes ;;; 28928; 3.8%
;;;;; method bytecode ;; 2911
;;;;; method structs ;; 3256 (#69475)
;;;;; constantpool ;; 10845
;;;;; classblock ;; 1441
;;;;; class ;; 2938 (#8350)
;;;;; other classdata ;; 4923
;;;;; overhead ;; 61
;;;; threads ;;; 109; 0.0%
;;;; malloc:ed memory ;;; 24479; 3.2%
;;;;; codeinfo ;; 1019
;;;;; codeinfotrees ;; 420
;;;;; exceptiontables ;; 585
;;;;; metainfo/livemaptable ;; 9489
;;;;; codeblock structs ;; 3
;;;;; constants ;; 7
;;;;; livemap global tables ;; 2183
;;;;; callprof cache ;; 0
;;;;; paraminfo ;; 89 (#1288)
;;;;; strings ;; 4997 (#92452)
;;;;; strings(jstring) ;; 0
;;;;; typegraph ;; 1527
;;;;; interface implementor list ;; 47
;;;;; thread contexts ;; 82
;;;;; jar/zip memory ;; 5451
;;;;; native handle memory ;; 41
;;;; unaccounted for memory ;;; 694751; 91.3%;28.38
---------------------!!!

[tomcat@swa158 ~]$
Tomcaty są skonfigurowane z -Xmx384M a pamięć wirtualna (VSZ) dla procesu po dwóch tygodniach wynosi 1192MB, RSS 900MB. Czyli o 500-800MB za dużo. Sama diagnostyka JRockita pokazuje unaccounted for memory 91.3%. Ta sama aplikacja chodząca bez Wily’ego zachowuje się poprawnie. Średnio na dzień wycieka około 50MB pamięci.
W rezultacie po pewnym czasie na produkcji wchodzimy w swapa (co już Wily pokazuje jako wydłużenie się requestów). Jedyne rozwiązanie to cotygodniowy restart tomcatów.

Wyciek mamy w natywnym kodzie. Znajdźmy jakieś natywne biblioteczki:
tomcat@swa175:~/tomcatDiag1/wily> find . -name *.so
./ext/libIntroscopeAIX4PSeries32Stats.so
./ext/libIntroscopeSolarisSparc64Stats.so
./ext/libIntroscopeRedHatStats.so
./ext/libIntroscopeHpuxParisc32Stats.so
./ext/libIntroscopeSolarisSparc32Stats.so
./ext/libIntroscopeSolarisAmd64Stats.so
./ext/libIntroscopeAIX52PSeries64Stats.so
./ext/libIntroscopeAIX53PSeries64Stats.so
./ext/libIntroscopeSolarisAmd32Stats.so
./ext/libIntroscopeHpuxItaniumStats.so
./ext/libIntroscopeAIX5PSeries32Stats.so
./ext/libIntroscopeAIX4PSeries64Stats.so

Zobaczmy jaki kod Javy odwołuje się do libIntroscopeRedHatStats.so:
tomcat@swa175:~/tomcatDiag1/wily> nm ./ext/libIntroscopeRedHatStats.so | grep Java
000015e2 T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getAggregateCPUUsage
0000158e T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getParentProcessID
000011c6 T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getProcessCPUUsage
0000153a T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getProcessID
00001524 T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getProtocolVersion
000017a0 T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getThreadCpuTime
0000148a T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_getTotalClockTicks
0000152e T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_init
00001796 T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_isThreadCpuTimeEnabled
00001534 T Java_com_wily_introscope_agent_platform_linux_LinuxPlatformStatisticsBackEnd_term

Zdekompilujmy JAD-em LinuxPlatformStatisticsBackEnd.class i poszukajmy podejrzanych metod ze słowem kluczowym native:
private native long[] getAggregateCPUUsage(String s)
throws PlaformStatUnavailableException;

Założę się, że char* wyjęte ze Stringa javowego nie jest zwalniane.

Podłączamy IBM JDK z parametrem -Xcheck:jni:all i widzimy:

JVMJNCK071W JNI warning: Memory at 0x080C22A0 acquired by GetStringUTFChars was not released before returning from native. This is probably a memory leak.
JVMJNCK078W Warning detected in com/wily/introscope/agent/platform/linux/LinuxPlatformStatisticsBackEnd.getAggregateCPUUsage(Ljava/lang/String;)[J

czyli Wily faktycznie ma wycieki pamięci. Shame on you CA!

Summary: One of Wily native libraries has improper interactions with Java VM via JNI - it doesn't free memory used for accessing Java strings. I have rewritten the library - sources and binary .so file are avalilable here (archive is protected with password).

czwartek, maja 28, 2009

Eurowybory

Będę głosował na człowieka z zasadami, który nie zmienia poglądów jak chorągiewka na wietrze, nie nakradł się, nie naoszukiwał. A okręgi wyborcze powinny być jednomandatowe.

środa, maja 27, 2009

Haszowanie PESELu

public class PH {

private static byte[] hash(String in, String key) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(key.getBytes());
return md.digest(in.getBytes());
}

private static String fillNumber(String s, int len) {
while (s.length() < len)
s = "0"+s;
return s;
}

private static String byte2String(byte[] b, int len) {
StringBuffer sb = new StringBuffer();
for (int i=0; i < Math.min(b.length, len); i++) {
int c = '0' + (b[i] & 0xff)%10;
sb.append((char)c);
}
return sb.toString();
}

public static void main(String[] args) throws Exception {
HashMap<String, String> map = new HashMap<String, String>();
int hc = 0;
for (int i=0; i < 100000; i++) {
String pesel = "721028" + fillNumber(i+"", 5);
String hash5 = byte2String( hash(pesel, "random123!"), 10);
if (map.get(hash5)!=null) {
System.err.println("Kolizja dla peselu "+pesel+" => "+hash5 + " => "+map.get(hash5));
hc++;
}
else
map.put(hash5, pesel);
}
System.err.println("Kolizji: "+hc);
}
}

Haszowanie PESELu ma być częściowe, czyli nie zmieniamy daty urodzenia, a tylko 5 ostatnich cyfr. Jeżeli ze standardowo zahaszowanego stringu z peselem wybierzemy poniżej 10 znaków (z 16) jako klucz, to mamy kolizje. Ponad 36000 na 100000 dla 5 znaków.

Workaround:
CREATE OR REPLACE
PROCEDURE HASH_OSOBY AS
type ROWID_TAB is table of rowid index by binary_integer;
collisions rowid_tab;
collisions_cnt number := 0;
passes number := 0;
key varchar2(4000) := 'klucz1';
err varchar2(4000) := '';
BEGIN
dbms_output.disable;
for rec in (select rowid from monitor.os) loop
begin
update monitor.os set pesel = haszujpesel(pesel, key) where rowid=rec.rowid;
exception when others then
collisions_cnt := collisions_cnt+1;
collisions(collisions_cnt) := rec.rowid;
err := SQLERRM;
insert into log_h(T,LOG) values(sysdate(),err);
end;
end loop;

insert into log_h(T,LOG) values(sysdate(), 'Pass '||passes||', number of collisions: '||collisions_cnt);
while collisions.count > 0 loop
key := key||key;
for i in collisions.first..collisions.last loop
begin
update monitor.os set pesel = haszujpesel(pesel, key) where rowid=collisions(i);
collisions.delete(i);
exception when others then
err := SQLERRM;
insert into log_h(T,LOG) values(sysdate(),err);
end;
end loop;
passes := passes + 1;
collisions_cnt := collisions.count;
insert into log_h(T,LOG) values(sysdate(), 'Pass '||passes||', number of collisions: '||collisions_cnt);
end loop;
END HASH_OSOBY;

Kończąc niniejsze rozważania należy powiedzieć, że w ramach ochrony danych osobowych dane testowe powinny zawierać w pełni zahaszowane PESELe, a o spójność PESELi z datami urodzenia po zahaszowaniu powinien zadbać autor bazy.

wtorek, maja 19, 2009

Fedora 11 rulez


  • PrintScreen wreszcie działa (wywołuje ksnapshot)
  • Sysinfo pokazuje temperaturę CPU
  • Filmy z tvp.pl działają (rpmfusion + xinelib*)
  • yum install kadu - w standardzie
  • yum install eclipse

piątek, maja 15, 2009

java.sql.ResultSet over DOM

Taki wrapper pozwala zachować stary kod operujący tylko na strukturach bazodanowych (rs.getInt...) i jako źródła danych używać obiektów zserializowanych do XML-a.

Node g = DOMHelper.getElementsByTag(p, "group-list").get(0);
rs = new DOMResultSet(g);
while (rs.next()) { // iteracja po węzłach poniżej group-list
// obiekt z wezła group
Group g = Group.fromResultSet(rs);
// w group wskazujemy węzły group-attrib
if (rs.findColumn("group-attrib")>0) {
while (rs.next()) {
GroupAttrib ga = GroupAttrib.fromResultSet(rs, g);
}
rs.refreshRow(); // kasujemy wskazanie
}
Debug.println("Wczytano "+rs.getString("."),this);
// "." oznacza biężący węzeł do zwrócenia jako string XML
}

piątek, maja 08, 2009

17W zużycia energii na mobilnym Athlonie i z GeForce 9100



Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
Option "RegistryDwords" "PowerMizerLevel=0x1"
Option "Coolbits" "1"
EndSection
Sterowniki to 185.18.08 beta. Czyli poprzedni krótki czas pracy na baterii to była wina NVidii.

czwartek, maja 07, 2009

Windows 7 dla użytkowników W2K3



Da się zrobić, żeby wyglądało po staremu.

Ciekawostka: szybka zmiana rozmiaru osadzonego okna w Przeglądarce Zdarzeń powoduje wywalenie się mmc.exe. Trochę obciach jak na Release Candidate. Nie czuć optymalizacji GDI.

sobota, kwietnia 25, 2009

Oracle Workshop for WebLogic 10.3 pod Linuksem

W przypadku wywalania się aplikacji na starcie należy wyedytować plik /bea/workshop_10.3/workshop.ini dodając linię:
-Dorg.eclipse.swt.browser.XULRunnerPath=/usr/lib/xulrunner-1.9 z poprawną ścieżką do XULRunnera.

Do Oracle Service Bus przydałyby się jakieś testowe WebService'y - są np. tutaj.

wtorek, kwietnia 21, 2009

Sun Fuji Milestone 5

Lekkie ESB techniczne (czyli w zasadzie sama warstwa routingu), w którym przepływy można wyklikać w przeglądarce. Do dyspozycji są adaptery: bazodanowy, http, jms, rss, ftp, email. Proste transformacje komunikatu mogą być dokonowywane przez węzły serwisowe JRuby.



Kiedy kontrolka JDBC będzie obsługiwać Oracle'a, będzie można zacząć myśleć o praktycznych zastosowaniach.

poniedziałek, kwietnia 20, 2009

Oracle buys Sun

No to teraz będą mieć trzy różne serwery aplikacyjne, dwie różne maszyny wirtualne i 2.5 ESB. Najważniejszym aspektem całego newsa jest to, że będą mieć system operacyjny i hardware, na którym najlepiej działa baza danych. Ultimate end user solution: SPARC + Solaris + Oracle 11g.

piątek, kwietnia 17, 2009

JRockit Mission Control

Śledzimy fragmentację...
JAVA_OPTS="-Xms384M -Xmx384M -Xmanagement:ssl=false,authenticate=false,autodiscovery=true"
JROCKIT_OPTS="-Xgc:genpar -XXcompactRatio:100"
JROCKIT_OPTS="-Xgc:singlecon -Xns32m -XXcompactRatio:100 -XXtlaSize:min=128K,preferred=512K -XXlargeObjectLimit=128K"



jrcmd 0 start_management_server
jrcmd 0 start_rmp_server

wtorek, kwietnia 14, 2009

Proxy na program

#include <windows.h>
#include <process.h>

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)

{
char* argv[32];
for (int i=0; i < 32; i++)
argv[i] = 0;

int argp = 2;
char *args = lpszArgument;
while(*args!=0) {
if (*args==' ') {
argv[argp++] = ++args;
args[-1] = 0;
}
}
argv[0] = "AppToFilterArgs.exe";
argv[1] = args;
return execv("AppToFilterArgs", argv);
}

Można prościej z ShellExecute(0, "open", "AppToFilterArgs.exe", args, NULL, SW_SHOW); albo bardziej skomplikowanie z CreateProcess. Pierwszy kod jest pod Windowsem blokujący - proces główny czeka na zakończenie AppToFilterArgs.exe (podobno _execv w oryginalnym VisualStudio 2005+ jest polecane jako zgodne ze standardem POSIX, jak tak dalej pójdzie to nie będzie już można polegać na błędach w oprogramowaniu MS...).

poniedziałek, kwietnia 13, 2009

G DATA AntiVirus 2010

W porównaniu do wersji 2009 zostały zmienione ustawienia silnika BitDefender (włączona analiza behawioralna), w ramach cloud security (czyli heurystyka sieciowa jak w Artemizie) podejrzane pliki wysyłane są do analizy. Zmieniło się GUI.



Oryginalny BitDefender 2009 ma funkcjonalność sprawdzania, czy zainstalowane oprogramowanie (Windows, przeglądarki internetowe, itp.) są w najnowszych załatanych wersjach.



niedziela, kwietnia 12, 2009

Analiza zmian po instalacji

Narzędzie TrackWinstall pozwala na porównanie stanu systemu sprzed instalacji danego programu ze stanem po instalacji. Narzędzie analizuje Rejestr oraz katalogi Windows i Documents and Settings. Żeby porównać inne katalogi można posłużyć się narzędziem junction od SysInternals i w katalogu Windows stworzyć hardlinka.

sobota, kwietnia 11, 2009

Jak włączyć McAfee Artemis w VirusScan Enterprise 8.7

Artemiza to nazwa dla technologii weryfikującej wskazania heurystyki po stronie serwera AVERT Labs. Obecnie włącza się ją oddzielnie dla każego komponentu: skanowanie na żądanie, skanowanie poczty, skanowanie przy dostępie. Pierwsze dwa załatwia zakładka wydajność:


Artemizę dla skanowania On Access włącza się w rejestrze w HKLM/Software/McAfee/VSCore/On Access Scanner:



Jak to działa? 50 klientów dobijało się do serwera z zapytaniem o plik trojan.exe o rozmiarze 256101 z pewną liczbą punktów dostarczoną przez analizę heurystyczną (liczba ta jednak była za mała do zaliczenia pliku do malware). 51 zapytanie dostanie odpowiedź, że to niebezpieczny plik, czyli zagrożenie Generic!Artemis.

SunBelt VIPRE

SunBelt ma własnego antywirusa. Firma twierdzi, że produkt jest szybki, nie wymagający dużo zasobów i ma bardzo dobrą wykrywalność. Subiektywnie rzecz biorąc działającej w tle Ochrony Aktywnej nie czuć, wszystkie komponenty zużywają 36MB RAM-u, zaś definicje wirusowe bazują na przepakowanych bazach Kaspersky'ego (plus wkład własny firmy SunBelt). Wygląda na to, że mamy fajnego antywirusa.




piątek, kwietnia 10, 2009

AntiVirenKit 2009

AVK miał parę lat temu dwa silniki: AVP i RAV. Po wykupieniu firmy GeCAD przez Microsoft, G DATA zmieniło drugi silnik na BitDefendera. I generalnie wszyscy byli/są przekonani że w AntiVirenKicie są silniki Kaspersky'ego i BitDefendera. Okazuje się jednak, że w wersji 2009 jest Avast i BitDefender (nazwane jako AV A i AV B)! Można to zobaczyć w Common Files\G DATA\AVKScanP.



Wersja korporacyjna ma Avasta i F-Prota. Kiedy ostatni raz robiłem testy antywirusów F-Prot był bardzo szybki, dzięki prostym sygnaturom, ale miał słabą heurystykę. BitDefender był pod względem wykrywalności mutacji lepszy. Teoretycznie komputer do pracy biurowej bywa słabszy od domowego, przeznaczonego do gier i dlatego powinien mieć antywirusa mniej spowalniającego system, ale czy wraz ze wzrostem wydajności musi spadać wykrywalność?



Skaner sieciowy (proxy) jest fajny.

Skaner plików ma prawdziwy wielowątkowy silnik pisany pod procesory wielordzeniowe. Domyślny priorytet skanera jest wysoki. W rezultacie na laptopie z odpalonym skanowaniem całego systemu czuć zapach prawie topiącego się plastiku. Szybkie obejście problemu to zmniejszenie priorytetu procesu AVK.exe i ustawienie maski afiniczności CPU za pomocą
Task Managera.

wtorek, kwietnia 07, 2009

BeOS is alive

Haiku pre-alpha. To by było genialne na netbooki.



Działa w VirtualBoksie 2.2, dysk VMDK.

poniedziałek, kwietnia 06, 2009

Jak wywalić JVM

import sun.misc.Unsafe;

public final class EvilCode {

public final static Unsafe getUnsafe () {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
return (Unsafe)field.get(null);
}
catch (Exception ex) {
throw new RuntimeException("can't get Unsafe instance", ex);
}
}

public final static void main(String[] args) {
Unsafe u = getUnsafe();
Random r = new Random();
for (int i=0; i < 1000000; i++) {
u.setMemory(r.nextLong(), 1L, (byte)0x0);
}
}
}

#
# An unexpected error has been detected by Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb7df628a, pid=7635, tid=3084217232
#
# Java VM: Java HotSpot(TM) Client VM (11.0-b16 mixed mode, sharing linux-x86)
# Problematic frame:
# C [libc.so.6+0x7528a] memset+0x1a
#

niedziela, kwietnia 05, 2009

Jak zrobić chmurę Java EE

Ja bym to zrobił tak:
  • Całość w oparciu o maszyny wirtualne VirtualBox odpowiednio z bazą Oracle XE, Postgresem i serwerem aplikacyjnym Apache Geronimo. Wirtualki byłyby tworzone z szablonów.
  • Środowisko deweloperskie (też wirtualne) na OpenSUSE 11.1 dostępne z apletu Javy w oknie przeglądarki bazujące na XRDP.
  • Ponieważ klient mógłby mieć parę wirtualek, to do usprawnienia autoryzacji wszystkie systemy podpięte byłyby do LDAP-a, na tej samej maszynie byłby SVN.
  • Na koncie użytkowika ustawiona by była qouta na fs, cpu, mem.
  • Interfejs do zarządzania infrastrukturą byłby zrobiony w Grailsach.
  • Wirtualki mogłyby wystawiać WebService'y dostępne z zewnątrz poprzez Apache ProxyPass.
  • Sewery: jeden na LDAP + SVN + Grails GUI + ProxyPass, następne hostujące konta użytkowników i maszyny wirtualne.
  • GUI w Grailsach przy okazji wystawiałoby serwisy, z których korzystałby bajerancki plugin do Eclipse'a.
Wersja beta szacowana na 2 osobomiesiące (z czego plugin do Eclipse'a 1 osobomiesiąc).
Skoro to takie proste, to teraz wszyscy zaczną oferować nam chmury...

Aptana Cloud

Wersja najtańsza oferuje 256MB i 5GB na MySQL-a i Tomcata-a. W wersji trial zużycie swapa wynosiło 40%, a z logów tomcata wynikało, że parę razy miał za mało pamięci, żeby wstać. Tną koszty. Całość działa w oparciu o kontenery Solaris-a 11. Mój kolega znający się na serwerach twierdzi, że ten cały cloud computing to nowa nazwa marketingowa na hosting, przy czym hosting jest tańszy. Patrząc na ofertę Aptany, przyznaję mu rację.











środa, kwietnia 01, 2009

Prawie niewidoczna autentykacja NTLM dla Acegi

Zrobiłem plugin NTLM zanim jeszcze SpringSecurity miał obsługę tej autentykacji. Założenie jest proste: korzystając z jCIFS i hasza dostarczonego przez IE logujemy się do kontrolera domeny. Jeśli autentykacja powiodła się to w formatce logowania zamiast hasła ustawiamy specjalny token sprawdzany po drugiej stronie przez plugin. Oprócz NTLM dodatkową autoryzacją jest LDAP (żeby na czyimś koncie windowsowym zalogować się jako inny użytkownik). Udostępniam przykładowy projekt, ponieważ w konfiguracji Grails 1.1 + Acegi 0.5 dostarczona przez Spring-a autoryzacja nie chce działać.