28/10/2010

Znikające Activity

Home

Na poniższym obrazku widać dwa schematy pochodzące z rożnych aplikacji, a przedstawiające fragment pewnego procesu biznesowego. Z prawej strony można zobaczyć definicję tego procesu, a z lewej powołaną do życia i uruchomioną jego instancję.



Niestety ale z jakichś powodów instancja różni się od swojej definicji. Pytanie dlaczego? Początkowo myślałem, że to jakiś problem z zapisywaniem lub odczytywaniem definicji/instancji procesu z bazy danych. Pomysł ten jednak szybko odrzuciłem ponieważ gdyby problem tkwił w tym miejscu to odczyt z bazy danych, deserializacja obiektu i w końcu wyświetlenie definicji/instancji procesu w standardowej kontrolce WorkflowView nie udało by się.

W dalszej kolejności zacząłem szukać różnic pomiędzy wspomnianymi aplikacji. Szybko udało się wykryć (dziękuję za pomoc Tomkowi), że kod brakującego Activity znajduje się w bibliotece niedostępnej dla aplikacji. Po skopiowaniu odpowiedniej dll'ki do katalogu z binariami aplikacji problem ustąpił.

Zacząłem się jednak zastanawiać czemu nie został zgłoszony żaden wyjątek informujący o braku dll'ki. Od razu pomyślałem, że ktoś musiał go przechwycić i zgasić. W sumie to się nie pomyliłem. Po włączeniu Managed Debugging Assistant dla wszystkich wyjątków (Debug -> Exceptions) i ponownym uruchomieniu aplikacji asystent pokazał, że wyjątek pojawia się w czasie deserializowania instancji procesu, gdzieś w środku klasy ActivityMarkupSerializer. Pojawienie się wyjątku nie przeszkadza jednak dokończyć deserializacji i zwrócić obiekt reprezentujący proces tylko, że bez kilku Activity.

Można powiedzieć, że ActivityMarkupSerializer jest bardzo sprytny ponieważ potrafi sobie poradzić nawet jeśli brakuje jakiejś biblioteki. Moim zdaniem ta klasa jest jednak za sprytna. Teraz już będę o tym wiedział ale na takim błędzie można stracić mnóstwo czasu.

27/10/2010

OciEnvCreate failed with return code -1

Home

OciEnvCreate failed with return code -1 to błąd na temat, którego można znaleźć w sieci sporo pytań ale mało odpowiedzi. Ja niestety miałem tego pecha i również na niego trafiłem, a w rezultacie straciłem kilka dobrych godzin. Błąd ten może pojawić się przy próbie nawiązania połączenia z bazą danych Oracle. Z informacji jakie znalazłem wynika, że najczęściej pojawia się w trzech przypadkach:
  • Brak zainstalowanych bibliotek klienckich Oracle.
  • Zła wersja zainstalowanych bibliotek klienckich Oracle.
  • Brak uprawnień użytkownika na jakim uruchomiony jest proces roboczy ASP.NET do katalogu z bibliotekami klienckimi Oracle.
Co do dwóch pierwszych scenariuszy to ani nie zaprzeczę i ani nie potwierdzę ponieważ na maszynie, na której napotkałem problem działał już program łączący się z bazą danych Oracle. W moim przypadku błąd pojawił się w usłudze webowej zainstalowanej na IIS'ie. Początkowo myślałem, że chodzi o coś zupełnie innego ponieważ tylko pierwsze odwołanie do wspomnianej usługi kończyło się błędem. Przy każdym następnym odwołaniu Web Service zachowywał się tak jakby działał tylko, że zwracał niepoprawne wyniki. No cóż pewnie ktoś gasił wyjątek! Przy pierwszym odwołaniu do usługi wołana jest natomiast metoda Application_Start zdefiniowana w pliku Global.asax, która w tym przypadku zawierała kod nawiązujący połączenie z bazą danych.

Kiedy już odkryłem pierwotną przyczynę niepoprawnego działania usługi postąpiłem zgodnie ze znalezioną sugestią i nadałem pełne uprawnienia do katalogów z bibliotekami Oracle, wstępnie użytkownikowi Wszyscy. Jednym z tych katalogów był C:\app\Administrator\product\11.1.0\client_1.

Następnie zrestartowałem pulę aplikacji do jakiej została przypisana usługa i sprawdziłem czy to coś zmieniło. Okazało się, że niestety nie. Spróbowałem jeszcze raz i nic. Po jakimś czasie stwierdziłem, że może chodzi o jakieś inne katalogi i zdesperowany nadałem użytkownikowi Wszyscy uprawnienia do całego dysku. Niestety znowu bez sukcesu. W tym momencie przyszło mi do głowy, że może nie wystarczy nadanie uprawnień i zrestartowanie puli aplikacji tylko trzeba dodatkowo uruchomić ponownie komputer, co też zrobiłem. Okazało się to strzałem w dziesiątkę.

Zadowolony z sukcesu postanowiłem tym razem zrobić wszystko po bożemu czyli cofnąć nadanie uprawnień wszystkim do wszystkiego i nadać pełne uprawnienia tylko jednemu użytkownikowi i tylko do jednego folderu, ewentualnie dwóch ale ściśle określonych. Na początek chciałem się jednak upewnić o jaki konkretnie folder chodzi i jakiego użytkownika. Postanowiłem więc wrócić do stanu początkowego kiedy błąd jeszcze występował. Jakie było jednak moje zdziwienie kiedy okazało się, że jest to niemożliwe ponieważ po cofnięciu nadania uprawnień i restarcie maszyny wszystko działa.

Reasumując niestety ale nie potrafię z 100% pewnością stwierdzić komu, do czego i jakie uprawnienia należy nadać. Faktem jest jednak, że instalator Oracle nie do końca poprawnie konfiguruje system w czasie instalacji. Faktem jest również, że nadanie prawdopodobnie pełnych uprawnień, prawdopodobnie do folderów wymienionych powyżej, prawdopodobnie dla użytkownika na jakim działa proces roboczy ASP.NET i prawdopodobnie restart komputera pomaga. Mam nadzieję, że te prawdopodobne stwierdzenie oszczędzi komuś kilka godzin pracy.

14/10/2010

Dziw nad dziwy

Home

Dzisiaj ponownie napiszę o błędzie z serii UFO. Przyjrzyjmy sie przez chwilę dwóm poniższym zapytaniom:

Zapytanie 1
select * 
from tabela1 t1
where exists ( select 1 from tabela2 t2, tabela3 t3
               where t2.kolumna = t3.kolumna and
                     t3.kolumna = t1.kolumna )


Zapytanie 2
select * 
from tabela1 t1
where exists ( select 1 from tabela2 t2, tabela3 t3
               where t2.kolumna = t3.kolumna and
                     t3.kolumna = t1.kolumna ) and 
t1.data = '14-10-2010'


Każdy zapewne zauważył, że drugie zapytanie różni się od pierwszego tylko dodatkowym warunkiem w zapytaniu zewnętrznym. Innymi słowy zapytanie 2 zawęża wynik jaki otrzymany w zapytaniu 1. A teraz pytanie:

Czy zapytanie 2 może zwrócić wiersze, które nie zostaną zwrócone przez zapytanie 1?

Część z was zapewne stuka się teraz w głowę i zastanawia się po co pytam o rzeczy oczywiste. Odpowiedź jest oczywiście oczywista i brzmi NIE ale, o zgrozo, nie dla każdej bazy danych. Niestety, w przypadku Informix'a w wersji 10 w ''sprzyjających'' warunkach odpowiedź będzie brzmiała TAK. Tak wiem, ja też przecierałem oczy ze zdziwienia kiedy koleżanka z pracy pokazała mi wynik dwóch powyższych zapytań.

Niestety dokładnych przyczyn problemu mogę tylko podejrzewać ale znam jego rozwiązanie. Otóż okazało się, że problem ustąpił po przeliczeniu statystyk przy pomocy poniższego polecenia:
UPDATE STATISTICS LOW 
FOR TABLE table_name (column1, column2...) DROP DISTRIBUTIONS
Polecenie to oblicza statystyki na tzw. niskim poziomie czyli przy założeniu, że rozkład wartości w danych kolumnach jest równomierny. Dodatkowo usuwa rozkłady wartości wyznaczane przy obliczaniu statystyk na poziomie średnim lub wysokim. Tak czy inaczej to ewidentny błąd w optymalizatorze zapytań, mechanizmie indeksów czy też statystyk, który obniża zaufanie do bazy danych.

Na koniec podziękowania dla Agnieszki, która pokazała mi ten błąd oraz dla Marcina, który znalazł rozwiązanie.

08/10/2010

MTS, MTS i po MTS'sie

Home

W konferencji Microsoft Technology Summit uczestniczyłem już po raz trzeci i ponownie jestem zadowolony. Pierwsze i najważniejsze prawie wszystkie sesje, które wybrałem wypaliły. Po drugie w tym roku było trochę luźniej i człowiek miał więcej przestrzeni wokół siebie. Udało mi się nawet zjeść obiad kulturalnie przy stoliku, a nie siedząc na ziemi. To oczywiście za sprawą mniejszej, o około 400, liczby uczestników w porównaniu do zeszłego roku. Nie wiem czy to kwestia polityki Microsoftu, wyższej ceny uczestnictwa, znudzenia konferencją... ale uważam, że wyszło to konferencji na plus. A więc, co wyniosłem z tegorocznej konferencji?
  • Bardzo pouczająca była dla mnie krótka rozmowa z Chrisem Grangerem, który pracuje w Microsofcie jako PM i był między innymi odpowiedzialny za nowy edytor czy rozszerzalność w VS 2010. Co w tym dziwnego/wyjątkowego? Chris ma 23 lata i zanim przyszedł do Microsoft nie miał styczności z ich produktami! Zapytałem go w jaki sposób został menadżerem. Odpowiedział, że w sumie to nie wie. Miał pracować jako programista ale został zaproszony na jeszcze jedną rozmowę, po której dostał pracę jako menadżer. Pozostaje tylko pogratulować. Zastanawiam się czy taka sytuacja byłaby możliwa w Polsce i jak zostałoby to odebrane przez zespół, w szczególności przez "starszych" pracowników.
  • Zobaczyłem jednych z najlepszych prelegentów jakich widziałem do tej pory. Mam tutaj na myśli głównie Marka Minasi i Davida Chapella. Tego ostatniego oglądałem niestety tylko kilkanaście minut ponieważ musiałem wyjść w ważnej sprawie.
  • Przekonałem się, że tematyka IT Pro to również coś dla mnie. Do tej pory wybierałem raczej sesje dla programistów, w tym roku zdecydowałem się na większe urozmaicenie i był to strzał w dziesiątkę. Szczególnie chwalę sobie sesję Marka Minasi na temat DNSSEC, po prostu super.
  • Zainteresowałem sie tematyką chmury obliczeniowej. To dziedzina jeszcze bardzo młoda i niedojrzała ale wygląda na to, że jesteśmy na to skazani. Może jeszcze nie teraz, może jeszcze nie za rok ale jak powiedział na swojej sesji John Craddock "Can we afford not to?"
  • O Task Parallel Library słyszałem, czytałem ale jeszcze nie używałem. Dzięki bardzo dobrej sesji Cezarego Nalewajki poznałem jej podstawy i teraz tylko czekam na okazję na jej użycie.
  • Dowiedziałem się o wcześniej nie znanym mi typie projektu w VS 2010, a mianowicie o Data-tier Application, który ułatwia instalowanie i konfigurowanie baz danych. Nowością była dla mnie również protokół OData. To wszystko na sesji Tomasza Wiśniewskiego.
  • Obserwując prelegentów nauczyłem się kilku rzeczy. Na przykład pytanie publiczności o to czy wszystko jasne, czy są jakieś pytania zachęca do ich zadawania. Podobny efekt odnosi dziękowanie za pytania. Podobało mi się również jak prelegent wyjaśnił, że w czasie sesji będzie siedział ponieważ na stojąco trudno kodować itd. Niby to wszystko oczywiste oczywistości ale takie rzeczy łatwo umykają.
  • Utwierdziłem się w przekonaniu, że należy jak ognia wystrzegać się swego rodzaju przerywników, pozwalających zebrać myśli, takich jak słowa OK/Dobrze. Jeden z prelegentów miał z tym problem. Swoją drogą jego sesja była fajna ale mogłaby być jeszcze fajniejsza.
  • Zobaczyłem na żywo jak sprawuje się nowy kontroler do XBox'a czyli Kinect.

23/09/2010

QR kody

Home

QR kod to dwuwymiarowy odpowiednik kodu kreskowego, który ostatnimi czasy staje się coraz popularniejszy. I ja o nim coś tam słyszałem ale do tej pory jakoś nie miałem z nim styczności, aż do dzisiaj.

Szukałem w sieci informacji na temat poleconego stomatologa. Znalazłem je na portalu tupalo czyli numer telefonu, adres, mapkę dojazdu no i jakiś dziwny czarno-biały obrazek. Przyglądam się i czytam, że to QR kod zawierający dane kontaktowe do rzeczonego specjalisty i wystarczy je zeskanować, żeby dodać kontakt do książki adresowej. Myślę sobie super ale ciekawe czy mój Samsung Galaxy GT-I5700 to potrafi. Okazało się, że jak najbardziej tak i już po chwili miałem zainstalowane dwie aplikacji QuickMark oraz BarcodeScanner do skanowania kodów dwu- i jednowymiarowych.

Najpierw przetestowałem skanowanie kodu jednowymiarowego czyli w moim wypadku kodu kreskowego na pierwszej lepszej książce. Wynik pozytywny, numer jaki pojawił się w telefonie zgadza się z numerem pod kodem kreskowym. Dalej coś trudniejszego. Skanuję QR kod wyświetlony na stronie i również sukces, zostaję zapytany czy dodać taki, a taki kontakt do telefonu. Postanawiam kontynuować zabawę i znajduję generator online QR kodów. Poniżej przykład jego działania, czy potrafisz go odczytać?



W postaci QR kodu zakodowałem również swój adres e-mail i umieściłem w lewym panelu bloga, może komuś się przyda. Zabawa, zabawą ale biorąc pod uwagę, że teraz właściwie już każdy posiada telefon komórkowy, bardzo dużo telefon komórkowy z aparatem fotograficznym, a spora grupa telefony, na których z łatwością można instalować nowe oprogramowanie to na rynku pojawia się (albo już sie pojawiła) nowa nisza do zagospodarowania.