Java EE vs Spring (nie pytam o zarobki)

0

Jak już wspomniałem, nie interesuje mnie za co więcej płacą(chociaż wydaje mi się, że zdecydowanie więcej za springa :) )

Nie mogłem znaleźć za dużo informacji na temat porównania tych platform, jedynie że Spring był zdecydowanie łatwiejszy w czasach starej Javy EE, natomiast teraz nie ma już takiej różnicy i oba rozwiązania są tak samo popularne i dobre.

Które rozwiązanie nauczy mnie więcej z zakresu aplikacji sieciowych i jest bardziej uniwersalne ?
Łatwiej prześć ze springa na Jave EE czy odwrotnie ?
Które rozwiązanie jest bardziej "naukowe" - w sensie które jest używane w jakiś instytuach i poważnych projektach naukowych, a nie startupach, gdzie projekty umierają po miesiącu, po czym powstaje 5 kolejnych w tym samym czasie.
Co ma większą renomę ? Jak reagujecie gdy ktoś ogarnia springa a jak gdy Jave EE :)

4
watpliwosci napisał(a):

Które rozwiązanie nauczy mnie więcej z zakresu aplikacji sieciowych i jest bardziej uniwersalne ?

Nauczy? Żadne, oba nieudolnie starają się ukryć rozproszenie aplikacji. Przy czym w Java EE, EJB - założenie oryginalne było takie, że potencjalnie każdy Bean działa w innym JVM, a tylko przypadkiem mogą być na jednej maszynie. W Springu, domyślnie beany sa na jednym JVM, a wyjątkowo, mogą być na różnych.

Robienie serwisów Rest wygląda w obu tak samo - i tak generalnie wygląda obecnie (mainstreamowe) robienie aplikacji sieciowych.

Warto zaznaczyć. Klasyczny Spring (popularne moduły) jest oparty o specyfikacje Java EE( Servlety, JPA itd).
Spring zawiera ponadtko dużo dodatków, modułów, któych nie ma w JavaEE.

Co więcej jest możliwe,praktycznie, robienie aplikacji, które będą działały zarówno w kontenerze Spring jak i pod serwerem aplikacji Java EE. (bez zmiany kodu).

Łatwiej prześć ze springa na Jave EE czy odwrotnie ?

Jeden pies.

Które rozwiązanie jest bardziej "naukowe" - w sensie które jest używane w jakiś instytuach i poważnych projektach naukowych, a nie startupach, gdzie projekty umierają po miesiącu, po czym powstaje 5 kolejnych w tym samym czasie.

Jakbyś patrzył co jest używane w poważnych projektach naukowych, to by Ci pewnie wyszedł NodeJS, R i Groovy :-) - na uczelniach sie wszytkiego używa, i raczej nie warto z tego wielkich wniosków wyciagać.

Jakkolwiek, obie platformy nie są w żadnym stopinu naukowe.

Z mojego punktu widzenia rdzeń obu platform (czyli beany) to zbrodnia na Javie i logice. Robienie PHP z Javy. Mamy język z kompilatorem, żeby nam sprawdzał błędy przed uruchominiem, ale korzystamy z framworka, który dodaje dużo magi (reflekcja, proxy, thread local) w runtime, po to żeby wywaliło się dopiero na produkcji... WTF?

Moim zdaniem, żaden poważny projekt, gdzie istotne są pieniądze. czas produkcji i jakość rozwiązania, nie powienien korzystać z Java EE lub klasycznego Springa.

Co ma większą renomę ? Jak reagujecie gdy ktoś ogarnia springa a jak gdy Jave EE :)

Renoma ? Czesto czuć niesmak jak się słyszy o Java EE, bo ludzie zapominają, że Spring to faktycznie to samo. Największy niesmak jest jak ktoś powie J2EE (buuuuu......)

Jak reaguje jak ktoś mówi, że ogarnia springa lub Java EE?
Zadaje pytanie kontrolne - z podstaw. Potwierdzam, że nie ogarnia i przechodzę do nastnęgo punktu (Btw. ja też nie ogarniam).

Warto zaznaczyć, że pewien pozdbiór Spring 5 - Sping WebFlux, nie dziedziczy nic po Java EE, jak również po Springu klasycznym . Jest to zupełnie inna historia (moim zdaniem WebFlux nie powienien nazywać się Spring). Natomiast pokazuje, że twórcy Springa przynajmniej słuchają trochę głosu ludu. Gdzie community Java EEJakarta EE odjechało już nawet nie wiadomo w jaką siną dal.

Z ciekawostek:
Kiedyś byłem wielkim miłośnikiem Java EE, EJB itd. Ale to było przed java 8 i zanim poznałem alternatywy.

6

Programistom Javy poleciłbym przerobić jakiś tutorial z PHP/CSS/HTML.
Tak, aby zobaczyć że do zrobienia stronki tej czy innej nie potrzeba InitialContextProxyEnterpriseInjectorFactory.
Potem oczywiście można się bawić w Java patterny (te czy inne), ale będzie się pamiętało jak to jest miło jak jest prosto.

2

@vpiotr: dobre :D Jednak z drugiej strony Spring Boot ukrył przed śmiertelnikami te dziwne klasy z nazwami dłuższymi niż normalne zdanie.
Przecież teraz RESTa można zrobić w 5 minut w Springu.

0

Już kilka razy słyszałem, że można zrobić to w 5 minut. Ja póbuję już tydzień - ale z logowaniem i wylogowaniem do tego api... wciąż nie mam pojęcia czego użyć.

4
vpiotr napisał(a):

Programistom Javy poleciłbym przerobić jakiś tutorial z PHP/CSS/HTML.
Tak, aby zobaczyć że do zrobienia stronki tej czy innej nie potrzeba InitialContextProxyEnterpriseInjectorFactory.
Potem oczywiście można się bawić w Java patterny (te czy inne), ale będzie się pamiętało jak to jest miło jak jest prosto.

To bardzo ciekawy aspekt kulturowy.
Zasadniczo to już 15 temu można było pisać w javaie tak jak w (klasycznym) PHP. Wystarzyło użyć JSP i taglibów (sql) i scriptletów. (przykład ze stronki: http://www.ntu.edu.sg/home/ehchua/programming/java/JSPByExample.html)

<html>
<head><title>First JSP</title></head>
<body>
  <%
    double num = Math.random();
    if (num > 0.95) {
  %>
      <h2>You'll have a luck day!</h2><p>(<%= num %>)</p>
  <%
    } else {
  %>
      <h2>Well, life goes on ... </h2><p>(<%= num %>)</p>
  <%
    }
  %>
  <a href="<%= request.getRequestURI() %>"><h3>Try Again</h3></a>
</body>
</html>

Tylko, że jak rozsądny javowiec chce dodać swie liczby to jednak nie może po chamsku zrobić 2 + 2, tylko musi użyć co najmniej MathManager.getMathematics().getSummationStrategyFactoryBuilderBean().forSimpleUniverse().build().createMaths().setFirstsNumber(2) [...] itd.

Btw. nie zachęcam do pisania w JSP, bo ma wiele wad PHP... ale czasami naprawe można robić prosto.

0

Odpowiadam tu bo w komentarzu by się nie zmieściło @jarekr000000
Mam bazę danych z użytkownikami i ich danymi, chciałbym aby była możliwośc zalogowania i wygenerowania tokenu (każdy user ma swoje hasło w tej tabeli), później każdy user może przy użyciu tego tokenu dodać nowe dane do swojej tabeli lub pobrać stare(tylko swoje) no i żeby przy wylogowaniu ten token był niszczony. Nie może być to zwykła strona tylko API, chce aby różne strony mógły się do tego podpiąć.
Ślepo ucze się Javy EE i Springa jednoczesnie w nadziei że w końcu któreś rozwiązanie doprowadzi mnie do zwycięstwa.

0

Nawiązując do tematu, ja nie wiem w sumie czy warto się tej Javy jeszcze uczyć.
Skoro mamy takie technologie jak Nodejs albo np. ultra fajny i prosty Go lang, dziwię się, że jeszcze powstają kolejne projekty w Springu.

W tym JSie niedługo już wszystko będzie można napisać ;p

3
NeutrinoSpinZero napisał(a):

Nawiązując do tematu, ja nie wiem w sumie czy warto się tej Javy jeszcze uczyć.
Skoro mamy takie technologie jak Nodejs albo np. ultra fajny i prosty Go lang, dziwię się, że jeszcze powstają kolejne projekty w Springu.

W tym JSie niedługo już wszystko będzie można napisać ;p

Java to nie tylko Spring czy JavaEE
W javie możesz pisać serwery, prosto i w podobny sposób, jak w NodeJS express (zobacz: wspomniany przeze mnie SparkJava).

Różnica jest jednak w Języku.

O JS to szkoda nawet mówić, a ten Go to jest tak fajny jak 30letni Wartburg.

Wcale nie kocham przesadnie Javy - wolę pisać w Scali, Haskellu i w najgorszym razie w Kotlinie.

Tym niemniej Java jest to jezyk dość dobrze zaprojektowany i mimo, że w najnowszych wersjach już się trochę robi syf - to nadal jest to projekt dużo lepszy od potworka JS. Brendan E. miał dobry pomysł, ale od razu go zrypał( podobno przez naciski marketingowców), nawet w najnowszych wersjach EcmaScript niestety nadal widać bolączki słabego początku - niektóre chyba już nie do naprawienia (truthy - chyba najgorsze, (==) !== (===) też słabe, choć w tym miejscu java ma też zwałkę, tylko na innym poziomie (== vs equals) i mniej niebezpieczną ).

Go ma jakis koncept, i to całkiem spójny, tylko jest to koncept zignorowania 30 lat postępu technicznego :-).
(Niedawno była dyskusja o tym: Crystal vs Go ,https://github.com/ksimka/go-is-not-good).

0

@jarekr000000: dobrze poczytać posty od kogoś dobrze zorientowanego :)
Ja jestem w programowaniu 1 rok dopiero, więc pełnię na razie rolę odtwórczą, nie mam prawa w sumie wydawać opinii, bo i na jakiej podstawie.
Często jednak się w necie angielsko języcznym natykam na wróżenie szybkiej śmierci padlinie - Javie.
Nieukrywam, że przez takie gadanie szukam alternatyw i współbierznie staram się zapoznawać pomału z innymi językami.

3
watpliwosci napisał(a):

Odpowiadam tu bo w komentarzu by się nie zmieściło @jarekr000000
Mam bazę danych z użytkownikami i ich danymi, chciałbym aby była możliwośc zalogowania i wygenerowania tokenu (każdy user ma swoje hasło w tej tabeli), później każdy user może przy użyciu tego tokenu dodać nowe dane do swojej tabeli lub pobrać stare(tylko swoje) no i żeby przy wylogowaniu ten token był niszczony. Nie może być to zwykła strona tylko API, chce aby różne strony mógły się do tego podpiąć.

To tutaj zalążek alternatywy:


import io.vavr.collection.HashMap;
import io.vavr.collection.List;
import io.vavr.collection.Map;
import io.vavr.control.Option;
import io.vavr.control.Try;
import spark.Spark;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;

import static spark.Spark.*;

public class LocationService {

    private DataService dataService = new DataService();

    public static void main(String[] args) throws InterruptedException {
        new LocationService().init();
        Thread.sleep(10000);
    }

    private void init() {
        Spark.exception(Exception.class, (exception, request, response) -> {
            try (ByteArrayOutputStream bous = new ByteArrayOutputStream();
                 PrintStream ps = new PrintStream(bous)
            ) {
                exception.printStackTrace(ps);
                response.body(bous.toString());
            } catch (IOException ioe) {
                //Exception while logging exception lol
                ioe.printStackTrace();
            }


        });

        path("session", () -> {
            post("/:login", (req, resp) -> {
                var login = req.params("login");
                var pass = req.body();
                return dataService.login(login, pass).getOrElse("");
            });
            delete("/:session", (req, resp) ->
                    dataService.logout(req.params("session"))
            );
        });
        path("location", () -> {
            get("/:session", (req, resp) ->
                    dataService.location(req.params("session"))
            );
            post("/:session", (req, resp)->
                dataService.addLocation(req.params(":session"), req.body())
            );
        });
    }


}

class UserData {
    public final String login;

    public final List<String> locations;

    UserData(String login, List<String> locations) {
        this.login = login;
        this.locations = locations;
    }

    //TODO probably not the best security
    boolean login(String password) {
        return login.equals(password);
    }

    public UserData addLocation(String newLocation) {
        return new UserData(login, locations.prepend(newLocation));
    }
}


class DataService {
    private final AtomicReference<Map<String, UserData>> users = new AtomicReference<>(HashMap.empty());
    private final AtomicReference<Map<UUID, String>> sessions = new AtomicReference(HashMap.empty());

    {
        users.getAndUpdate(users -> users.put("irek",
                new UserData("irek", List.of("Pcim"))));
        users.getAndUpdate(users -> users.put("jurek",
                new UserData("jurek", List.of("Pcim Dolny"))));
    }

    Option<String> login(String login, String password) {
        return users.get().get(login)
                .filter(u -> u.login(password))
                .map(u -> UUID.randomUUID())
                .peek(uuid ->
                        sessions.updateAndGet(s -> s.put(uuid, login))
                )
                .map(u -> u.toString());
    }

    Boolean logout(String uuidString) {
        return Try.of(() -> UUID.fromString(uuidString))
                .map(uuid -> sessions.getAndUpdate(s -> s.remove(uuid))
                        .containsKey(uuid)).getOrElse(false);

    }

    List<String> location(String uuid) {
        return userSession(uuid).map(user -> user.locations)
                .getOrElse(List.empty());
    }

    List<String> addLocation(String uuid, String newLocation) {
        return userSession(uuid)
                .map(user -> user.addLocation(newLocation))
                .peek(user -> users.updateAndGet(u -> u.put(user.login, user)))
                .map(user -> user.locations)
                .getOrElse(List.empty());
    }

    private Option<UserData> userSession(String uuidString) {
        return Try.of(() -> UUID.fromString(uuidString))
                .toOption()
                .flatMap(uuid -> sessions.get().get(uuid))
                .flatMap(userLogin -> users.get().get(userLogin));
    }

}

Do projektu trzeba dodać dwie zależności:

    compile 'com.sparkjava:spark-core:2.7.2'
    compile 'io.vavr:vavr:0.9.2'

Korzystanie:

login
> curl -X POST -d 'irek' localhost:4567/session/irek
3354ca35-6939-48e6-9ff4-51711bd53886

logout
> curl -X DELETE localhost:4567/session/707f0438-02db-4c5c-aa9c-492a7ec98939

lokacje
> curl localhost:4567/location/3354ca35-6939-48e6-9ff4-51711bd53886
List(Pcim)

dodanie lokacji
>  curl -d 'Kostomłoty' localhost:4567/location/3354ca35-6939-48e6-9ff4-51711bd53886
List(Kostomłoty, Pcim)

Oczywiście security w powyższym jest zabawne, ale to sobie poprawisz. Baza jest w pamięci więc nie wyłączaj kompa i będzie dobrze :-).

0

@jarekr000000: kolejny mikroserwis, piszę w Sparku :)

4

@NeutrinoSpinZero: tak na prawdę powinieneś pisać aplikacje tak, żeby nie miało znaczenia czy potem odpalasz to sparkiem, ratpackiem, springiem czy czymś innym

0

@danek: czyli apkę zależną tylko od JDK ? :D

btw.
@jarekr000000: skąd czerpiesz takie różne ciekawe informacje dot. debaty nad technologiami itd.? Jest jakieś takie scentralizowane miejsce, czy raczej samo wpada podczas przeglądania różnych treści?

2

Nie, chodzi mi o architekturę. Oddzielenie samej logiki aplikacji od spraw związanych z restem itp (najprościej po przez fasady itp) Dzieki temu otrzymujesz samą aplikacje którą możesz łatwo testować prawie, że integracyjnie (czy jak tam nazywać  testy które nie są integracyjnymi, a dotykają wiecej niż jednej klasy) w pamięci.

1

Jakarta EE is dead jeśli chodzi o nowe projekty. Teraz to Szpring króluje w ogłoszeniach o prace...

0

dla pełności obrazu EE vs Spring trzeba wspomnieć Adama Biena i Antonio Concalvesa (YT, mają własne blogi). Reprezentują kierunek zwany "single dependency Java EE (7,8)"

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