Jak naprawić zablokowane Static Files w Oracle APEX

23 października 2015, Michał Wyszyński

Pracując przy rozwoju istniejących aplikacji Oracle APEX wiele razy spotkałem się z problemem nie dających się odświeżyć Static Files. Objawiało się to następująco: po usunięciu starej wersji pliku (np. biblioteki javascript) i dodaniu pliku z poprawkami, APEX uparcie nie chciał odświeżyć źródła i zwracał starą wersję pliku. Nie mogłem się nadziwić jak to możliwe – przecież usunąłem poprzednią wersję pliku. Odświeżanie, ani czyszcze cache przeglądarki nie pomagało. Najskuteczniejszym sposobem było załadowanie pliku pod inną nazwą i zmiana linku w szablonie strony.

Pewnego dnia, gdy kolejny raz musiałem przez to wszystko przechodzić, postanowiłem że znajdę przyczynę problemów i ją naprawię.

Prywatne śledztwo

Zacząłem od ustalenia, czy problem leży po stronie klienta (przeglądarki), czy po stronie bazy danych (Oracle APEX). Ponieważ już wcześniej zauważyłem, że czyszczenie cache przeglądarki nie pomaga, moje pierwsze podejrzenia padły na APEXa. Jednak, żeby wyeliminować ryzyko pomyłki, do weryfikacji mojej tezy użyłem innej przeglądarki niż tej z której korzystam na co dzień do pracy. Weryfikacja polegała na ręcznym wywołaniu żądania pobrania pliku źródłowego. Jeśli jeszcze tego nie wiecie, to można to zrobić przy pomocy linku, który wygląda mniej więcej tak:

Oczywiście zamiast #WORKSPACE_ID# oraz #filename# należy podstawić odpowiednio identyfikator workspace APEX i nazwę pliku, który chcemy pobrać. Część &p_flow_id=#APP_ID# występuje jeśli dany plik jest przypisany do aplikacji. Powyższy URL można w prosty sposób uzyskać przy pomocy konsoli np. w Chrome, należy w zakładce Resources odnaleźć interesujący nas plik (dla javascript będzie to Frames -> (f)-> Script). Więcej informacji o zarządzaniu plikami w Oracle APEX znajdziecie w tym wpisie.

Wywołanie takiego URLa zwróciło mi starą wersję skryptu. Czyli miałem rację – wina stoi po stronie Oracle Application Express!

Kolejnym krokiem było przeszukanie internetu w poszukiwaniu dowodów na to, że nie jestem pierwszym, który ma taki problem. Nietrudno było znaleźć wpisy osób, które pytały się jak sobie z tym poradzić. Trudniej było znaleźć jakieś odpowiedzi. Po przekopaniu się przez tonę postów na różnych forach w końcu trafiłem na coś co dawało nadzieję na rozwiązanie zagadki. Na forum OTN trafiłem  na wpis z 2008 roku dla APEXa w wersji 3.0.1 . Okazuje się, że ten sam problem występuje nadal w wersji 4.2.1. ! Wpis znajduje się tutaj.

W skrócie: problem polega na tym, że próbując załadować plik o takiej samej nazwie jak plik już wcześniej dodany, dostaniemy błąd o naruszeniu więzów unikalnych. Wszystko by było OK, gdyby nie to, że mimo wszystko plik zostaje załadowany do APEXa! Nie można go usunąć, bo z poziomu APEXa go nie widać. Jeśli nawet usuniemy starą wersję tego pliku (tą przez którą nie mogliśmy poprzednio prawidłowo załadować nowego pliku) i załadujemy nową wersję pliku, to z dużym prawdopodobieństwem APEX zacznie w aplikacji odnosić się do „niewidzialnego” pliku. I nawet jeśli następnym razem najpierw usuniemy starą wersję pliku i wgramy nową, to APEX cały czas będzie serwował nam „niewidzialny” plik w starej wersji.

Rozwiązanie

Na rozwiązanie tego problemu natknąłem się na tym blogu. Jak łatwo się domyśleć, polega ono na ręcznym „posprzątaniu” tego bałaganu. Aby móc dostać się do plików przechowywanych przez APEXa, musimy najpierw ustawić kontekst. W tym celu należy wykonać następujące kroki:

  1. Należy zalogować się na schemat na którym stoi workspace APEXa (ewentualnie skorzystać z SQL Workshop).
  2. Wykonać poniższy skrypt:
    Do zmiennej :workspace_name należy podać nazwę workspace, na którym znajdują się problematyczne pliki.
  3. Następnie, aby znaleźć ukryte wersje pliku naszego pliku wywołujemy zapytanie:
    Jeśli widać zduplikowane wpisy, które różnią się tylko tym, że niektóre mają null w kolumnie FILE_TYPE, to mamy kandydatów do usunięcia.
  4. Upewniamy się, że to te pliki: należy zweryfikować nazwę pliku i FLOW_ID (id aplikacji do której są przypisane – 0 oznacza WORKSPACE_IMAGES).
  5. Wybrane pliki usuwamy za pomocą:
    gdzie :id to identyfikator pliku z wcześniejszego punktu.

Jeśli chcemy sprawdzić, jakie pliki mogą potencjalnie sprawiać problemy z ich aktualizacją możemy wywołać takie zapytanie:

 Podsumowanie

Co prawda nie udało mi się naprawić źródła problemu (to już leży po stronie twórców Oracle Application Express), ale udało mi się zlokalizować przyczynę tego dziwnego zachowania. Dodatkowo, znając naturę tego błędu, można zawczasu ustrzec się przed jego przykrymi konsekwencjami. A jeśli wystąpi, to wiadomo jak sobie z nim poradzić. Warto jednak zachować ostrożność przy czyszczeniu tabeli wwv_flow_files, ponieważ możemy niechcący usunąć jakiś bardzo ważny plik, bez którego któraś z aplikacji przestanie działać. Jeśli nie ma pewności co do usuwanego pliku, można przed jego usunięciem zrobić backup, tak na wszelki wypadek.

Problem ten nie występuje w przypadku plików przechowywanych na serwerze (w katalogu /i/), a jedynie w przypadku plików trzymanych w bazie danych. Sprawdzałem ten scenariusz również na APEX 5 i za pomocą przedstawionych w poście kroków nie da się go odtworzyć. Wygląda na to, że Oracle w najnowszej wersji uporał się z tym przypadkiem.

Tagi: , , , , , , ,

Zapraszamy do kontaktu!

Pretius jest firmą tworząca oprogramowanie wspierające biznes.
Tworzymy aplikacje webowe wykorzystując: Java, Oracle DB, Oracle Apex, AngularJS.
Skontaktuj się z nami, aby porozmawiać o tym jak możemy pomóc w realizacji Twojego projektu!