„Nie wymyślaj koła na nowo” to jedna z głównych zasad udanej i wydajnej pracy. Co jednak zrobić, gdy nie chcesz wymyślać własnego koła na nowo, a kierownica kogoś innego okazuje się krzywa, a koła są kwadratowe? Celem tej recenzji jest jak najkrótsze wprowadzenie do techniki naprawiania bibliotek innych osób „w ostateczności” oraz sposobu rozszerzenia tej możliwości na swój komputer.
Przed zaimportowaniem projektu wprowadźmy pewne zmiany w pliku opisującym sposób budowania. Plik ten nazywa się skryptem kompilacji i nosi nazwę build.gradle. Znajduje się w katalogu, w którym wykonaliśmy gradle init. Dlatego po prostu go otwieramy (na przykład w Windows za pomocą polecenia start build.gradle). Znajdujemy tam blok „ zależności ”, czyli tzw. zależności. Wszystkie słoiki innych firm, których będziemy używać, są opisane tutaj. Teraz musimy zrozumieć, co tu opisać. Przejdźmy do strony Hibernate ( http://hibernate.org/ ). Jesteśmy zainteresowani Hibernate ORM . Potrzebujemy najnowszej wersji. W menu po lewej stronie znajduje się podsekcja „Wydania”. Wybierz „najnowszą stabilną”. Przewiń w dół i znajdź „Wdrożenie podstawowe (w tym JPA)”. Wcześniej konieczne było osobne podłączenie obsługi JPA, ale teraz wszystko stało się prostsze i wystarczyła tylko jedna zależność. Będziemy także musieli pracować z bazą danych za pomocą Hibernacji. Aby to zrobić, weźmy najprostszą opcję - Baza danych H2 . Wybór został dokonany, oto nasze zależności:
Trochę niezdarny przykład, ale załóżmy, że chcemy zmienić liczbę spacji zapytań przy uruchomieniu. Jak widzimy, nasze zapytanie sqlQuery to NativeQueryImpl. Kliknij
Od razu zaznaczmy, że Idea nie wie obecnie, gdzie znaleźć kod źródłowy programu (czyli kod źródłowy). Dlatego uprzejmie zdekompilowała dla nas zawartość pliku klasy:
Zauważ też, że w tytule okna IntelliJ Idea jest napisane, gdzie Gradle zapisuje dla nas artefakt. Przejdźmy teraz do Idea, gdzie znajduje się nasz artefakt:
Przejdźmy do tego katalogu w wierszu poleceń za pomocą polecenia
Teraz skompilujmy plik. My robimy:
Hurra, teraz możesz przeprowadzić aktualizację słoika. Możemy kierować się oficjalnymi materiałami :
Świetnie. Ale tu pojawia się pytanie - z powodu czego? Po prostu dlatego, że kiedy Gradle buduje projekt, analizuje blok zależności i repozytoriów. Gradle ma określoną pamięć podręczną kompilacji, która znajduje się w określonej lokalizacji (zobacz „ Jak ustawić lokalizację pamięci podręcznej gradle? ” Jeśli w pamięci podręcznej nie ma zależności, Gradle pobierze ją z repozytorium. Ponieważ zmieniliśmy słoik w cache, wtedy Gradle myśli, że biblioteka znajduje się w pamięci podręcznej i niczego nie wypompowuje. Ale jakiekolwiek wyczyszczenie pamięci podręcznej doprowadzi do utraty naszych zmian. Poza tym nikt poza nami nie może po prostu iść i je pobrać. Ile niedogodności , prawda? Co robić. Hmm, pobieranie z repozytorium? Potrzebujemy więc naszego repozytorium, z preferencjami i poetkami. To jest kolejny krok.
Kliknij „Rozpocznij przesyłanie”, a następnie „Zapisz pliki”. Następnie pojawi się zielony komunikat o powodzeniu, a artefakt stanie się dostępny w sekcji „Przeglądaj”. Należy to zrobić dla plików jar i pom:
Wynika to z faktu, że w pliku pom określone są dodatkowe zależności hibernacji. A pozostał nam tylko 1 krok - określ repozytorium w naszym skrypcie kompilacji:
Wstęp
Wszyscy używamy tego czy innego narzędzia. Czasami jednak narzędzia nie są w pełni odpowiednie lub zawierają błędy. Dzięki funkcjom języka Java możemy korygować zachowanie narzędzi tam, gdzie tego potrzebujemy. Dobrze, gdy współtworzymy projekty i wysyłamy pull requesty (więcej możesz przeczytać tutaj: „ GitHub – Współtworzenie projektów ”). Ale mogą nie zostać zaakceptowane natychmiast lub nawet nie zostać zaakceptowane. Ale na potrzeby projektu jest to konieczne teraz. I tutaj, mam nadzieję, ten artykuł pokaże narzędzia, którymi dysponujemy jako programiści. Będziemy musieli wykonać następujące kroki, o których będziemy mówić:- Przygotuj np. aplikację testową (na przykładzie projektu Hibernate)
- Znalezienie zmiennej lokalizacji
- Dokonywanie zmiany
- Wdrażanie repozytorium
Przygotowanie przedmiotu
Potrzebujemy więc projektu testowego. Hibernacja jest dla nas idealna, ponieważ... jest „stylowy, modny, nowoczesny”. Nie będę się wdawać w szczegóły, bo... Artykuł nie dotyczy hibernacji. Wszystko zrobimy szybko i na temat. A my, podobnie jak prawdziwi programiści, będziemy korzystać z systemu kompilacji. Na przykład odpowiedni jest dla nas Gradle, który należy zainstalować na potrzeby tego artykułu ( https://gradle.org/install/ ). Najpierw musimy stworzyć projekt. Maven ma do tego archetypy , a Gradle ma do tego specjalną wtyczkę: Gradle Init . Otwórz więc wiersz poleceń w dowolny znany ci sposób. Utwórz katalog dla projektu, przejdź do niego i wykonaj polecenie:
mkdir javarush
cd javarush
gradle init --type java-application
dependencies {
// Базовая зависимость для Hibernate (новые версии включают и JPA)
compile 'org.hibernate:hibernate-core:5.2.17.Final'
// База данных, к которой мы будем подключаться
compile 'com.h2database:h2:1.4.197'
// Use JUnit test framework
testCompile 'junit:junit:4.12'
}
Świetnie, co dalej? Musimy skonfigurować Hibernację. Hibernate ma „ Przewodnik wprowadzający ”, ale jest on głupi i bardziej przeszkadza niż pomaga. Przejdźmy więc od razu do „ Podręcznika użytkownika ” jak właściwi ludzie. W spisie treści widzimy sekcję „ Bootstrap ”, co oznacza „Bootstrapping”. Tylko to, czego potrzebujesz. Jest tam napisanych sporo mądrych słów, ale chodzi o to, żeby w ścieżce klas znajdował się katalog META-INF i plik Persistence.xml. Zgodnie ze standardem ścieżka klas zawiera katalog „zasoby”. Dlatego tworzymy określony katalog: mkdir src\main\resources\META-INF
Utwórz tam plik trwałości.xml i otwórz go. Tam w dokumentacji znajduje się przykład „Przykład 268. Plik konfiguracyjny META-INF/persistence.xml”, z którego pobierzemy zawartość i wrzucimy ją do pliku Persistence.xml. Następnie uruchamiamy IDE i importujemy do niego stworzony przez nas projekt. Teraz musimy zapisać coś w bazie danych. Jest to coś zwanego bytem. Podmioty reprezentują coś z tak zwanego modelu domeny. A w spisie treści widzimy „ 2. Model domeny ”. Schodzimy w dół tekstu i w rozdziale „2.1. Typy mapowania” widzimy prosty przykład encji. Weźmy to dla siebie, trochę skracając:
package entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity(name = "Contact")
public class Contact {
@Id
@GeneratedValue
private Integer id;
private String name;
public Contact(String name) {
this.name = name;
}
}
Mamy teraz klasę reprezentującą byt. Wróćmy do pliku trwałości.xml i poprawmy tam jedno miejsce: Tam, gdzie jest to wskazane, class
wskażemy naszą klasę entity.Contact
. Świetnie, pozostaje tylko uruchomić. Wróćmy do rozdziału Bootstrap . Ponieważ nie mamy serwera aplikacji, który udostępni nam specjalne środowisko EE (czyli środowisko realizujące za nas określone zachowanie systemu), pracujemy w środowisku SE. W tym celu odpowiedni jest dla nas tylko przykład „Przykład 269. Aplikacja ładowana EntityManagerFactory”. Zróbmy to na przykład:
public class App {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("CRM");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Contact contact = new Contact("Vasya");
em.persist(contact);
em.getTransaction().commit();
Query sqlQuery = em.createNativeQuery("select count(*) from contact");
BigInteger count = (BigInteger) sqlQuery.getSingleResult();
emf.close();
System.out.println("Entiries count: " + count);
}
}
Hurra, nasz temat jest gotowy. Nie chciałem pominąć tej części , bo... W następnych rozdziałach wskazane jest zrozumienie, jak powstał nasz temat.
Znalezienie modyfikowalnego zachowania
Zajmijmy miejsce inicjalizacji pola licznikowego typu BigInteger i ustawmy tam punkty przerwania ( BreakPoint ). Po wstawieniu na żądaną linię można to zrobić za pomocą Ctrl+F8 lub poprzez menu Uruchom -> Przełącz punkt przerwania linii. Następnie uruchamiamy naszą główną metodę w debugowaniu (Uruchom -> Debuguj):Ctrl+N
, wpisz nazwę zajęć i przejdź do nich. Tak, że gdy udamy się na zajęcia, zostaniemy przeniesieni do miejsca, w którym znajdują się te zajęcia i włączymy autoprzewijanie:
cd sposób na каталогу
. Od razu zaznaczę: jeśli można zbudować projekt ze źródeł, lepiej jest budować ze źródeł. Na przykład kod źródłowy Hibernate jest dostępny na oficjalnej stronie internetowej. Lepiej jest wybrać żądaną wersję, wprowadzić tam wszystkie zmiany i złożyć, korzystając ze skryptów kompilacji określonych w projekcie. W artykule przedstawiam najstraszniejszą opcję - jest słoik, ale nie ma kodu źródłowego. I uwaga nr 2: Gradle może uzyskać kod źródłowy za pomocą wtyczek. Aby uzyskać szczegółowe informacje, zobacz Jak pobrać dokumentację javadoc i źródła jar przy użyciu Gradle .
Dokonywanie zmiany
Musimy odtworzyć strukturę katalogów zgodnie z pakietem, w którym znajduje się klasa, którą zmieniamy. W tym przypadku:mkdir org\hibernate\query\internal
, po czym tworzymy plik w tym katalogu NativeQueryImpl.java
. Teraz otwieramy ten plik i kopiujemy tam całą zawartość klasy z IDE (tego samego, które zdekompilował dla nas Idea). Zmień niezbędne linie. Na przykład:
javac org\hibernate\query\internal\NativeQueryImpl.java
. Wow, nie można tego po prostu wziąć i skompilować bez błędów. Otrzymaliśmy kilka błędów związanych z brakiem możliwości znalezienia symbolu, ponieważ... klasa zmienna jest powiązana z innymi klasami, które IntelliJ Idea zwykle dodaje za nas do ścieżki klas. Czy czujesz całą użyteczność naszych IDE? =) No cóż, dodajmy to sami, my też możemy to zrobić. Skopiujmy ścieżki dla:
- [1] - hibernate-core-5.2.17.Final.jar
- [2] - hibernate-jpa-2.1-api-1.0.0.Final.jar
Ctrl+Shift+C
. Utwórzmy teraz i wykonajmy następujące polecenie: javac -cp [1];[2] org\hibernate\query\internal\NativeQueryImpl.java
W rezultacie obok pliku Java pojawią się nowe pliki klas, które należy zaktualizować w pliku jar:
jar uf hibernate-core-5.2.17.Final.jar org\hibernate\query\internal\*.class
Open IntelliJ Idea najprawdopodobniej nie pozwoli na zmianę plików. Dlatego przed wykonaniem aktualizacji słoika najprawdopodobniej będziesz musiał zamknąć Idea, a po aktualizacji otworzyć go. Następnie możesz ponownie otworzyć IDE i ponownie uruchomić dubug. Punkty przerwania nie są resetowane pomiędzy ponownymi uruchomieniami IDE. Dlatego wykonywanie programu zatrzyma się tam, gdzie było wcześniej. Voila, widzimy, jak działają nasze zmiany:
Wdrażanie repozytorium
Istnieją różne bezpłatne rozwiązania do wdrażania repozytorium: jedno z nich to Artifactory , a drugie to Apache Archive . Artifactory wygląda modnie, stylowo, nowocześnie, ale miałem z nim trudności, nie chciałem poprawnie umieszczać artefaktów i generowałem błędne metadane mavena. Dlatego nieoczekiwanie dla mnie wersja Apache zadziałała dla mnie. Okazało się, że nie jest tak pięknie, ale działa niezawodnie. Na stronie pobierania znajdź wersję samodzielną i rozpakuj ją. Mają swój własny „ Szybki Start ”. Po uruchomieniu musisz poczekać na adreshttp://127.0.0.1:8080/#repositorylist
. Następnie wybierz „Prześlij artefakt”:
repositories {
jcenter()
maven {
url "http://127.0.0.1:8080/repository/internal/"
}
}
I odpowiednio wersja naszej hibernacji będzie: compile 'org.hibernate:hibernate-core:5.2.17.Final-JAVARUSH'
. To wszystko, teraz nasz projekt korzysta z poprawionej przez nas wersji, a nie oryginalnej.
Wniosek
Wygląda na to, że się poznaliśmy. Mam nadzieję, że było ciekawie. Takie „sztuczki” zdarzają się rzadko, ale jeśli nagle wymagania biznesowe postawią warunki, których biblioteki, z których korzystasz, nie są w stanie spełnić, wiesz, co robić. I tak, oto kilka przykładów, które można poprawić w ten sposób:- Istnieje serwer WWW o nazwie Undertow. Do pewnego czasu występował błąd, który podczas korzystania z serwera proxy nie pozwalał nam poznać adresu IP użytkownika końcowego.
- Na razie WildFly JPA poradziło sobie w pewien sposób z jednym momentem nieuwzględnionym w specyfikacji, z tego powodu rzucone zostały wyjątki. I nie było to konfigurowalne.
GO TO FULL VERSION