Wątek przeniesiony 2020-12-11 15:16 z Inżynieria oprogramowania przez cerrato.

Jak nie usunę tej lombokomi to chce lobotomii.

0

Mam projekt w Javie, który ma wszędzie napchane lomboka, 2 osoby, ktore go ogarnialy poszly, zostalem tam wrzucony. Chce się go pozbyć, czy da sie to zrobić jakoś z głową?
Jest jakiś plugin do którego mozna miec zaufanie i który mi to pozamienia w kod?

0

Idea ma delombokizację,
Lub z linii komendy (jest udokumentowane)
https://projectlombok.org/features/all
szukaj delombok

2

Tylko się zastanów czy naprawdę tego chcesz. Jeżeli działa i nie sprawia problemów to nie ma co sobie na siłę życia utrudniać. Przy odrobinie szczęścia nie będziesz musiał robić upgrade'u Javy (co zazwyczaj psuje lomboka) więc prawdziwe kłopoty Ciebie ominą...

Radzę zainstanować sobię wtyczkę Lombokową w IDE.

0

Pytanie czy tutaj nie ogarniasz lomboka czy innych frameworków/bibliotek które masz dodane a które korzystają z wygenerowanego kodu.

Sama delomobkizacja nic nie da bo lombok to tylko cukier syntaktyczny jak nie lubie adnotacji to w przypadku lomboka nie ma tam żadnej magii. Poza tym po delombokizacji powstanie tona kodu.

3

No nie wiem - faktycznie jak na javę adnotacje to te lombokowe są wyjątkowo mało popaprane (bo są aplikowane w czasie buildu/kompilacji).
Tym niemniej, taki ostro zlombokowany kod potrafi wypalać oczy. Byłem w takim projekcie kiedyś - w ciągu kilku dni stałem się wojującym alombokistą.
Kod był taki, że ciężko było dostrzeć cos poza adnotacjami (oprócz lomboka, była też cała reszta śmietanki).

0

Delombok robi paskudnie napisane equals/hashcody, zwróć se na to uwage, jeśli użyjesz

1

@jarekr000000: Wlaśnie o to chodzi, moim zdaniem z prostych rzeczy powstał over engineering z adnotacjami, Napchane jest tego tyle, że hej.
Czasem trafi sie jakaś fajna adnotacja, to można uzyć, ale generować z tego wszystko to przesada.

2

Usuń niepotrzebne adnotacje lombokowe, a potrzebne zostaw.

Np RequiredArgsConstructor pewnie mógłby zostać, ale wszystkie @data, @Getter @EqualsAndHashCode @ToString, jak nie używane to wywal.

2

Pozerzy z was. Ja nienawidziłem Lomboka zanim to było modne.

Tak już trochę na serio - Lombok to świetny przykład na to, jak działa moda w programowaniu. Kiedyś wszędzie można było znaleźć artykuły o tym, jaki Lombok nie jest wspaniały. Teraz kiedy widzę w końcu Lomboka w bankach inwestycyjnych to Lombok powoli odchodzi w odstawkę. Zobaczymy, czy teoria się potwierdzi przy okazji Kotlina.

0

Tylko czy to nie jest tak, że Loombook zawiódł grupę zawodową produkcyjnych programistów, a ludzie piszący dla siebie odnajdują w nim faktycznie ukrócenie kodu? Bo czasami mam takie wrażenie czytając takowe (jak i nie takowe) tematy o nim.

3

Jak dla mnie Lombok to rozwiązanie dla ludzi, którzy już odkryli, że java to jednak bieda z nędzą (w danym zastosowaniu), ale boją się do tego przyznać i kombinują jak tu użyć innego języka, tak, żeby nie mówić, że to jednak inny język.

Lombok to nie jest java. To inny język: taki bieda kotlin o składni przypominającej kupę.
A co do mody zgadzam się. Sam kiedyś byłem prolombokowcem - też byłem na tym etapie, że bałem się przyznać, że już mi java nie pasuje.

5
jarekr000000 napisał(a):

Jak dla mnie Lombok to rozwiązanie dla ludzi, którzy już odkryli, że java to jednak bieda z nędzą (w danym zastosowaniu), ale boją się do tego przyznać i kombinują jak tu użyć innego języka, tak, żeby nie mówić, że to jednak inny język.

Lombok to nie jest java. To inny język: taki bieda kotlin o składni przypominającej kupę.
A co do mody zgadzam się. Sam kiedyś byłem prolombokowcem - też byłem na tym etapie, że bałem się przyznać, że już mi java nie pasuje.

"only sith deal in absolutes".

Nie wiem czemu, z jakiegoś powodu większość ludzi się uparła na "100% full lombok" albo "uninstall lombok".

Jeez, żyj i daj żyć. Użyj lomboka tam gdzie jest sens i można (@RequiredArgsConstructor, @Slf4j jak chcesz logi; @SneakyThrows czasem, może @HashCodeAndEquals TAM GDZE TRZEBA), i tyle. Nie wpychaj setterów i getterów na siłe. Nie dopisuj @ToString, żeby było; Nie rób każdego objectu @Data, bo tak.

Słowiem: użyj narzędzia tam gdzie jest sens; nie używaj tam gdzie nie ma. Simple

1

W projektach które używały lomboka zazwyczaj używaliśmy tylko gettery/settery/builder/noargsconstructor/allargsconstructor/requiredargsconstructor i w sumie te elementy mi się podobały a przesadzić można zawsze i ze wszystkim.

3

Przy okazji przypomniało mi się holenderskie (a może niemieckie?) przysłowie: Zanim zburzysz mur, upewnij się że wiesz dlaczego go wybudowano ;)

0

Może czegoś nie rozumiem, ale dla mnie Lombok to głównie @Data i jak tylko Java 14 pojawi się w mojej firmie i będzie to miała to co Pascal miał od czasów Gierka ( Pascalowe rekordy), to jestem gotów zapomnieć o Lomboku.

A tak konkretnie co było w Pascalu? to kopiowanie całych struktur bez pisania kodu (lombok @With AFAIK).

Pascal

    program ideone;
    type
        TRec = record
           num  : Integer;
           st   : String;
        end;
    var
      rec1, rec2: TRec;
    begin
    	rec1.num := 1;
    	rec1.st := 'aaa';
    	rec2 := rec1;
     
    	writeln(rec2.st);
    end.

https://ideone.com/tGV034

Java

class Rec {
	public int num;
	public String st;
}
 
 
class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		Rec rec1 = new Rec();
		rec1.num = 1;
		rec1.st = "aaa";
 
		//rec2 = ...
 
		System.out.println(rec2.st); // NPE, więcej kodu trzeba!
	}
}

Zresztą porównywanie struktur i toString też jest przydatne.

0

Nie rozumiem ani hejtu ani jarania się Lombokiem. Generator kodu, jakiś preprocesor. Nic wielkiego. Pracowałem z nim 1.5 roku i nie problemów.
To był ryzykowny bajer w tym temacie https://www.eclipse.org/Xtext/ ale wyszło.

2

Jak nie mam nic do preprocessorów i sam chętnie je używam to z kolei jestem hejterem Lomboka za to w jaki sposób on działa.
Normalny preprocessor (na przykładzie projektu mavenowego) działa tak, że bierze źródła klasy z katalogu src/main/java i wypluwa źródła definicji nowej klasy do target/generated-sources/annotations, zaznaczam, nowej klasy, czyli z nową nazwą klasy.
A Lombok? Bierze źródła klasy z src/main/java i podczas kompilacji dorzuca jakiś bytecode, ponieważ jakby wygenerował kod źródłowy to projekt by się nie skompilował, bo miałby dwie definicje tej samej klasy, jednej w src, a drugiej w target.
Inne preprocessory, np. immutables.org to bierze źródła klasy ValueObject i generuje nowe źródła nowej klasy ImmutableValueObject i jest spoko.
Lombok bierze źródła klasy XYZ i wypluwa bytecode XYZ z dodatkowymi metodami ponieważ w javie nie ma czegoś takiego jak partial class.

1

Jak dla mnie to najlepsze połączenie dają dwie zwykłe adnotacje @Value i @Builder. @Value w sobie zawiera trochę innych, ale jeśli mówimy o jakimś VO albo "normalnej" klasie, a nie żadnej encji JPA, to przyjemnie się z tym pracuje.

0

Jedni popierają lomboka inni nie...kto jest za lombokiem a kto przeciw ? jakie adnotacje najczęściej używacie?

3

Ja używam Lomboka i póki co nie widzę powodu by porzucać. Jestem zadowolona z efektu. Dobrze mi się z nim żyje.
Najczęściej jest to zestaw adnotacji:

@Value
@Builder

stosuję standardowo dla DTO oraz konstruktory:

@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

Innych rzeczy praktycznie nie używam.

Dlaczego używam? - No cóż jest to wygodne. Jedna adnotacja @Value i mam niemutowalny obiekt z podstawowymi metodami (toString, hash, equals, getter). Podobnie oszczędza mi to czasu i potencjalnych błędów, dostarczając buildera.

Niby preprocesowanie kodu to magia, ale ta magia jest prosta i stabilna - nie miałam nigdy większych problemów. No miałam jeden problem kiedyś jak dodałam drugi preprocesor :D Jakbyście mieli np. mapstruct processora i lomboka, to wtedy (na pewno w gradle'u, nie jestem pewna czy maven sobie radzi) jest problem, jeżeli kolejność zależności w dependencies jest nieodpowiednia, co jest smutne (taki hak, że mapstruct processor musi być zdefiniowany w dependencies przed lombok processorem). No i to pokazuje, że Lombok jest fajny, ale potencjalnie jak się zacznie dołączać kolejne preprocesory, to może się zacząć problem, który wołać pierwszy itp.

1

Ja nie lubię adnotacji do konstruktorów w klasach które nie są DTOsami, utrudnia to debugowanie i ogarnięcie kodu. Wolę podejście takie jakie jest w keczupie przy konstruktorach

0

Lombok dodaje lukier składniowy do javy.

Nie przepadam za lombokiem ale tutaj wypunktuję dlaczego:

  1. Lombok nie będąc składnią języka java powodował, że do IDE musiałem instalować dodatkowe pluginy, bywało tak, że po aktualizacji IDE wysypywał się zainstalowany plugin, a aktualizacji pluginu nie było.
  2. Gdy systemem budującym jest maven i lombok generowałby dodatkowe klasy zamiast edytowałby bytecode już obecnych to wystarczyłoby, że każde IDE zgodne z systemem budowania maven nie potrzebowałoby pluginów, a to w dzisiejszych czasach jest pewniejsze niż obsługa lomboka poprzez dodatkowy plugin.
  3. Tutaj mogę się mylić, ponieważ nie jestem pewien, ale adnotacja @Data generuje m.in. settery, equals i hashCode, czyli zakładam, że zawołanie jakiegoś settera z innym parametrem niż jest obecnie ustawiony w obiekcie spowoduje, że zawołanie kolejny raz hashCode zwróci inny wynik, a w dokumentacji javy jest napisane, że equals i hashcode powinno być konsekwentne, czyli w przypadku hashCode zawsze zwracać ten sam wynik w czasie życia obiektu, a equals wielokrotnie z zadanym parametrem zawsze powinien zwracać ten sam wynik.
  4. Zwykle to adnotacja @Data jest używana do generowania setterów i getterów zamiast użycie tych dwóch: @Setter i @Getter, żeby nie było annotation hell, ale użycie @Data ciągnie za sobą generowanie hashCode i equals (patrz punkt wyżej), już nie mówię o tym, że IDE zwykle mają skróty na generowanie setterów i getterów.
  5. Uważam, że pracując z osobami, które nie wiedzą czym jest Value Object nie powinno dołączać się lomboka do projektu, ponieważ dzięki temu nie ma wtedy możliwości użycia adnotacji lombokowych tj. @Data, @EqualsAndHashCode które prowadzą do autoimplementowania hashCode i equals.
  6. Jedyne "sensowne" adnotacje z lomboka to @Value oraz @Builder, ale wolałbym już wtedy użyć biblioteki immutables, ale to już kwestia gustu.

Wydaje mi się, że traktowanie lomboka jako standard w obecnych javowych projektach oznacza, że sama gramatyka języka java nie spełnia oczekiwań programistów.

4

@ivo:
Jeśli chodzi o:

że zawołanie jakiegoś settera z innym parametrem niż jest obecnie ustawiony w obiekcie spowoduje, że zawołanie kolejny raz hashCode zwróci inny wynik, a w dokumentacji javy jest napisane, że equals i hashcode powinno być konsekwentne,

To akurat nie jest wina Lomboka. To sam hashCode w javie jest porypany po całości, a to powyżej to jeden z problemów. Najgorszy problem to taki, że hashCode jest zrobiony jako metoda do pokrywania w Object (dobrze, że nie wrzucili tam compareTo - bo byłoby jeszcze śmieszniej).

Sama koncepcja robienia jakiś klas w buildzie nie jest taka straszna (lepiej niż w runtime). Fakt, że Lombok, w odróżnieniu od innych podobnych narzędzi, robi to w pojarany sposób. (Widocznie autorzy wciągali te same kadzidełka co twórcy javy i metody hashCode).

0

Bez sensu. Po co chcesz usuwać tego Lomboka? W przypadku wielu javowych projektów, może on pomóc jedynie zredukować boilerplate. Problemy mogą być chyba jedynie wtedy jak masz kilka bibliotek, które generują kod i wchodzą ze sobą w konflikt. Lombok jest tylko do zwykłych encji i nie widzę w nim wielkiego problemu, choć słyszałem, że podobno ktoś kiedyś miał z tym jakieś problemy. Za delombokizacją idzie kupa niepotrzebnej roboty i pełno dodatkowego kodu. Gdybyś pisał projekt od nowa, to mógłbyś sobie zrobić założenia, że nie masz Lomboka, ale jak projekt istnieje, to IMO jest to strata czasu, jeśli jedynym powodem do zmiany jest osobista fanaberia, a nie jakieś konkretne argumenty.

Odpowiadając na Twoje pytanie, jak chcesz się pozbyć Lomboka, to musisz po prostu usunąć wszystkie adnotacje Lomboka, usunąć wszystkie zależności do Lomboka z pom.xml / build.gradle, a potem przekleić/przepisać ręcznie kod wygenerowany przez Lomboka do Twoich encji. W katalogu build/classes (w przypadku gradle) po przebudowaniu projektu znajdziesz kod wygenerowany przez Lomboka i możesz go nawet zdekompilować z poziomu IntelliJa i przekleić na chama do swoich klas, jak bardzo chcesz.

PS. w najnowszej javie ma dojść data class, która, mam nadzieję, rozwiąże ten spór raz na zawsze :) (choć builderów z automatu tam pewnie nie będzie :()

0

@ivo:

Uważam, że pracując z osobami, które nie wiedzą czym jest Value Object nie powinno dołączać się lomboka do projektu, ponieważ dzięki temu nie ma wtedy możliwości użycia adnotacji lombokowych tj. @data, @EqualsAndHashCode które prowadzą do autoimplementowania hashCode i equals.

Przecież @Value dostarcza hashcode/equals i to String. Tutaj jest napisane:

In practice, @Value is shorthand for: final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter, except that explicitly including an implementation of any of the relevant methods simply means that part won't be generated and no warning will be emitted.

czyli w przypadku hashCode zawsze zwracać ten sam wynik w czasie życia obiektu, a equals wielokrotnie z zadanym parametrem zawsze powinien zwracać ten sam wynik.

Szczerze mówiąc o tym nie wiedziałem ale dokumentacja (https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() mówi jasno:

Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.

2

@scibi92:
Wiem o tym, że @Value dostarcza hashCode i equals, ale nie zastosuje się tej adnotacji np. na encjach JPA, ponieważ one muszą mieć publiczny bezargumentowy konstruktor oraz pola muszą być mutowalne, więc często widziałem takie kwiatki, że zamiast użyć dwóch adnotacji @Getter i @Setter na encjach, jest użyta jedna @Data, bo mniej linii kodu to niby lepiej. Ale @Data niesie za sobą autogenerowanie hashCode i equals, które opierają się na mutowalnych polach, a mutowalność pól jest wymagana w encji JPA. A to, że specyfikacja mówi coś jasno to jedna sprawa, a to, że to skompiluje się i zostanie wrzucone na produkcję to druga sprawa ;)
W większości przypadków zwykła domyślna implementacja czy to wygenerowana przez lombokowe @Data lub @EqualsAndHashCode czy tam przez skrót klawiszowy w IDE generuje kod niezgodny właśnie z dokumentacją javy. Chodzi mi o to, że to właśnie nicnierobienie jest częściej zgodne z dokumentacją javy niż nadpisywanie hashCode i equals przez programistę, czy to za pomocą przypadkowego użycia lomboka czy przez wygenerowanie kodu z poziomu IDE.

2

Ja używam bo nie lubie boilerplate'u. Wolę 2 adnotację (@Builder i @Value) niz czesto 200 linijek jakiegos zlomu wygenerowanego z IDE. Pozniej nie wiadomo, czy gdzies tam moze w 150 linijce ktos cos nie dopisal do gettera, to samo dotyczy setterow, konstruktorow i builderow. Wszystko trzeba recznie przejrzec w razie W.

Najbardziej brakowaloby mi builderow bo te wygenerowane z IDE i tak trzeba jeszcze poprawic.

Do apek CRUDow brak lomboka to jakis dramat bo tam 90% kodu to boilerplate ktory mozna by ogarnac 2 adnotacjami

2
ivo napisał(a):

w dokumentacji javy jest napisane, że equals i hashcode powinno być konsekwentne, czyli w przypadku hashCode zawsze zwracać ten sam wynik w czasie życia obiektu, a equals wielokrotnie z zadanym parametrem zawsze powinien zwracać ten sam wynik.

No właśnie jest napisane dokładnie coś przeciwnego, jeżeli zmienią się elementy używane w equals, to i hash code może się zmienić. Chyba, że mówisz o wymaganiach gdzieś indziej, że hashCode ma być stały, ale wtedy nie jest to wina Lomboka, tylko jego niepoprawnego użycia. Ja wiem, że jest prawo Hyruma, ale to nie zwalania z czytania dokumentacji i rozumienia LSP.

2

@Afish ma rację.

Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.

Jeśli więc jakieś pole jest zmienione i jest używane w equals to hashcode powinien być zmieniony.

4

Ta ostatnia wymiana zdań na temat hashCode pokazuje jak bardzo jest to zrypane w javie.

Sam hashCode i equals faktycznie może się swobodnie zmieniać... no chyba, że z niego korzystamy, bo trzymamy obiekty w jakimś HashMap, HashSet czy w jakiejś innej strukturze korzystającej z mieszania.
Jeśli w obiekcie tak refereowanym zmieni się hashCode to mogą dziać się ciekawe rzeczy - od wycieków pamieci aż do całkiem dziwnych wywałek.
Czyli, zmieniać można - jeśli wiadomo, że akurat nigdzie nie jest wykorzystany, a to nie jest zawsze wiadomo, jest wiele niejawnych miejsc, gdzie taki hashCode może być użyty - sesje jpa na przykład.

Dawno, dawno temu (jak byłem architekte) preferowałem idealny hashCode:
public int hashCode () {return 1;}, bo
taki jest zgodny ze specyfikacją zawsze, pięknie działa w aplikacjach biznesowych, gdzie rzadko mamy hashMapy większe od 10 elementów, no i w razie czego będzie wiadomo kiedy trzeba zmienić, bo system zacznie klękać.

Przestałem tak robić, bo ludzie jednak nie potrafią zrozumieć, komentować mi się nie chce, a osoby przejmujące system przeważnie nawet nie umieją obsłużyć ani monitoringu ani profilera.

Obecnie skłaniam się ku o wiele lepszemu rozwiązaniu:
public int hashCode () {throw new UnsupportedOperationException();}

(ale jeszcze nigdzie nie stosowałem - boję się, że znowu nikt nie zrozumie).

1 użytkowników online, w tym zalogowanych: 0, gości: 1