Problem z konfiguracją frameworka Google Guice

Problem z konfiguracją frameworka Google Guice
R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
1

Witam.
Próbuje napisać prostą aplikację w frameworku Google Guice. Niestety podczas kompilacji występuje błąd którego nie mogę rozwiązać.
Brzmi on następująco: "No implementation for java.util.List was bound. while locating java.util.List for field at Operator.carShops(Operator.java:17) while locating Operator ()"
i odnosi się do settera wykorzystującego listę obiektów (Bez tej listy program działa poprawnie).

Ponizej zamieszczam kod programu:

Kopiuj
public class Main {
public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        Operator operator = injector.getInstance(Operator.class);

        operator.prepareData();
}}



public class Operator implements IOperator {
@Inject
private List<CarShop> carShops;

public List<CarShop> getCarShops() {
    return carShops;                             <--- Miejsce wystąpienia błędu
}

public void setCarShop(List<CarShop> carShops) {
    this.carShops = carShops;
}

public void prepareData() { 
    for(CarShop carShop:carShops)
        for(int i=0;i<10;i++) {
            Car car = new Car();
            car.setPrice(1000);     
            carShop.addCar(car);
        }
}}

Proszę o jakieś wskazówki, ponieważ nie mogę dojść przyczyny powstania tego błędu.
Pozdrawiam

edytowany 1x, ostatnio: ralf2005
artur52
  • Rejestracja:prawie 11 lat
  • Ostatnio:11 miesięcy
  • Lokalizacja:Warszawa
  • Postów:223
0

Nigdzie nie inicjalizujesz tej listy, że jest to ArrayList czy LinkedList,
Poza tym wstrzykuj przez konstruktor :<

jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 23 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
0

Taka rada wywal ten Google Guice i pisz bez niego. I będzie szybciej i nie będziesz miał głupich problemów (a jeszcze zaosczedzisz pare mb na dysku). To nie chodzi o to, że to zły framework. Tu chodzi o to, że moim zdaniem do niczego go nie potrzebujesz.


jeden i pół terabajta powinno wystarczyć każdemu
R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

Inicjalizuje tą listę w innej klasie. Poniżej przedstawiam jej implementacje:

Kopiuj

import com.google.inject.Inject;

import java.util.ArrayList;
import java.util.List;

public class CarShop{

	public CarShop() {
	}

	@Inject
	private Owner owner;
	private List<Car> cars = new ArrayList<Car>();
	private String name = "Salon nr 1";

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Owner getOwner() {
		return owner;
	}
	public void setOwner(Owner owner) {
		this.owner = owner;
	}
	public List<Car> getCars() {
		return cars;
	}

	public void setCars(List<Car> cars) {
		this.cars = cars;
	}
	
	public void addCar(Car car) {
		cars.add(car);
	}
}

Co to frameworka Google Guice jest mi niezbędny do ukończenia projektu. Pozdrawiam

jarekr000000
Ale skąd wiesz, że Ci jest potrzebny jak nawet nie wiesz co robi? :O
R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

jarekr000000, Ponieważ muszę przygotować projekt w wyżej wymienionej technologii :)

edytowany 1x, ostatnio: ralf2005
jarekr000000
  • Rejestracja:ponad 8 lat
  • Ostatnio:około 23 godziny
  • Lokalizacja:U krasnoludów - pod górą
  • Postów:4708
2

offtopic: po kimś powtarzam, ale nie pamiętam po kim:
To chyba jest największy dramat IT. Ludzie robią projekty na uczelnie albo w ramach rekrutacji z zadaniem użyj frameworka X. A potem dostają pracę i zaczynają robić projekt i jeszcze nie wiedza czy to bedzie strona Web kiosku spożywczego, czy system kontroli ruchu na lotnisku, ale do pom.xml już leci:

Kopiuj
<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>4.1.0</version>
</dependency>

(albo spring)


jeden i pół terabajta powinno wystarczyć każdemu
edytowany 3x, ostatnio: jarekr000000
R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

Szkoda, że nie umiejąc pomóc tylko snujesz filozoficzne wywody. Proszę, żebyś już nic nie pisał jak nie masz nic do powiedzenia na temat tej technologii.

Pozdrawiam

jarekr000000
Przepraszam, ale nie moge Ci pomóc bo twoje zadanie nie ma nawet sensu. Nie ma czegoś takiego jak napisz z użyciem Guice. Guice to narzędzie do rozwiązania konkretnego problemu, jak go nie masz to bedzie trudno go zrobić.
jarekczek
Jak posiedzisz tu dłużej, to zobaczysz, że @jarekr000000 miesza z błotem każde napomknięcie o JavaEE albo Dependency Injection. Trzeba to ignorować :) . Powinien to wrzucić do stopki. Ale warto go czytać.
nie100sowny
  • Rejestracja:około 9 lat
  • Ostatnio:22 minuty
  • Lokalizacja:Kraków
  • Postów:402
0

Skoro tak arogancko się odnosisz do wiedzy to proszę odpowiedź:

Klasa SklepSamochodów posiada listę Samochodów (lista jest zainicjalizowana - dokładnie pusta).
Operator ma listę SklepówSamochodowych (lista jest nie zainicjalizowana, będzie wstrzykiwana z Guice)
A gdzie zadeklarowałeś Guice listę SklepówSamochodowych do wstrzyknięcia???
NIGDZIE.

Ale z takim tonem to będziesz co najwyżej programistą ~ "Hurra działa i nic mnie nie obchodzi. Przecież działa."


"Gdy się nie wie, co się robi, to się dzieją takie rzeczy, że się nie wie, co się dzieje"
edytowany 3x, ostatnio: nie100sowny
R2
Mógłbyś coś więcej o tym powiedzieć? Moim zdaniem adnotacja @Inject powinna załatwić sprawę.
nie100sowny
No to jaki obiekt Guice wstzryknie dkoro wszystko jasne? Listę z 0 / 100/ milionem/ bilionem elementów? Pomyśl. Musisz stworzyć moduł, i zbindować interfejs List z instancją. Dodatkowo jako, że List to interfejs tak popularny warto temu Beanowi przypisać nazwę.
R2
Mógłbyś powiedzieć jak zbindować taką listę? Ponieważ dopiero zaczynam przygodę z Guice.
nie100sowny
Tak to bardzo proste. Wystarczy wpisać w Google :P Ale łatwiej będzie nie wykorzystywać Guice. :)
R2
Właśnie jeżeli chodzi o listy nie mogę znaleźć nic co mnie interesuje, podzielił byś się linkiem?
czysteskarpety
czysteskarpety
  • Rejestracja:około 10 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Piwnica
  • Postów:7697
0
jarekr000000 napisał(a):

offtopic: po kimś powtarzam, ale nie pamiętam po kim:
*To chyba jest największy dramat IT. Ludzie robią projekty na uczelnie albo w ramach rekrutacji z zadaniem użyj frameworka X.

dziwisz się? pełno obecnie stanowisk "Programista Frameworka xxx" ludzie dostosowują sie do rynku i tyle...


jarekr000000
Nie powiniem narzekać - praktycznie moja pierwsza praca ne etacie to programista XML. (akurat jak zaczynałem etat i kończyłem z "freelance" - to była bańka internetowa 2000 i takie głupoty nawet nie wydawały się wszystkm śmieszne)
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@ralf2005 ten kod generalnie nie ma sensu. Skąd się niby Guice ma domyślić co ma zrobić? W ogóle w tym kodzie nie widze nigdzie zadnej listy CarShop a sam CarShop nie jest beanem CDI nawet.
Anyway:

  1. Oznacz Operator jako @Named
  2. Oznacz wszystko co chcesz wstrzykiwać jako @Named (więc ten twój nieszczęsny CarShop)
  3. Oznacz tam gdzie chcesz wstrzykiwać przez @Inject

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
Zobacz pozostałe 8 komentarzy
R2
Nie jest to oczywiscie cały kod, jednak do tego zagadnienia taka jego część wystarczy. W Springu adnotacja @Autowired automatycznie dopasowuje tutaj potencjalne klasy.
Shalom
To może tak: ty nam pokażesz konkretny kod który ma sens i który nie działa, a powinien a my go poprawimy? Bo teraz pokazałeś coś co sensu nie ma i nie będzie działać chocbyś składał ofiary z dziewic i niemowląt...
R2
Nie wiem czemu ktoś wtrącił, że dany kod nie ma sensu. Program ma sens. Jest to aplikacja, która korzysta z mniejszych komponentów umieszczonych w kontenerze, tak aby nie było konieczności za każdym razem tworzyć nowych obiektów (Jedynie dla zobrazowania problemu posłużyłem się krótszym przykładem). Chodzi o to, że bez korzystania z komponentu Operator program działa. Jednak przy próbie skorzystania z niego pojawia się błąd o którym jest poruszony cały ten temat.
Shalom
Kawałek kodu który pokazałes nie ma sensu. Teraz to sobie mozemy wróżyć z kart bo nie wiadomo co ci nie działa bo nie wiadomo co ty w ogóle uruchamiasz.
R2
Ok, to od początku. Mam metodę Main. W niej pobieram sobie zarejestrowane przez Guice komponenty. Są tam takie byty jak klasa Car, Owner itd. Jest też klasa Operator, która posiada listę obiektów CarShop - klasa do zarządzania CarShopami. dopóki nie korzystam w aplikacji z komponenu zawierającego listy innych obiektów, to wszystko działa ok. W przypadku próby skorzystania z tego komponentu (Wykorzystującego listę) program zgłasza błąd rejestracji komponentu Operator.
R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

Z tego co udało mi się teraz ustalić to rzeczywiście jest problem z klasą Operator. W przypadku zdefiniowania Interfejsu i pobierania wartości za pomocą:

Kopiuj
IOperator operator = injector.getInstance(Operator.class);

Jest zgłaszany błąd Bindingu.

Dla sprecyzowania binding jest przeprowadzony w następujacy sposób:

Kopiuj
bind(IOperator.class).to(Operator.class);

W przypadku skorzystania z

Kopiuj
Operator operator = injector.getInstance(Operator.class);

Jest zgłaszany problem dotyczący niepoprawnie zdefiniowanego Providera.

Ktoś spotkał się może z takim problemem?

edytowany 2x, ostatnio: ralf2005
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

Jeśli chcesz wstrzykiwać wszystkie implementacje danej klasy (a zgaduje że po to ci ta lista?) to w Guice nie ma tak łatwo i trzeba https://stackoverflow.com/questions/6085200/how-to-get-all-implementors-subclasses-of-an-interface-with-guice
Analogicznie takie cos nie działa tez z Weldem. To jest tylko takie "rozszerzenie" CDI które ma Spring.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
Zobacz pozostałe 9 komentarzy
R2
Pomińmy kwestię, czy wstrzykiwanie takich obiektów jest rzeczą odpowiednią. Rzeczywiście tutaj masz całkowitą rację - "Gdzieś tą liste trzeba utworzyć". Niestety nie wiem dlaczego w Springu to działa, a tutaj nie (Tam nigdzie nie daję new na liście). Z dokumentacji wynika, że adnotacja @Inject odpowiada niemalże dokładnie adnotacji @Autowired. W takim razie powinno też tutaj wystąpić wypełnienie listy, poprzez dopasowanie po klasie.
Shalom
Ale to zadziała dla jednego obiektu a nie dla ich listy, bo nic oprócz Springa nie wspiera takiego wstrzykiwania listy.
R2
Ok, interesuje mnie jeszcze wcześniejszy komentarz użytkownika nie100sowny. Bo, z tego co wnioskuję to przy poprawnym zbindowaniu takiej Listy nie trzeba by było używać operatora new do jej utworzenia. Niestety nie mam kompletnie pojęcia w jaki sposób można by to było zrobić (Wiem jak jedynie bindować Interfejsy na klasy). Masz może wiedzę na ten temat?
Shalom
Jeśli nie pokażesz kodu to z fusów nie wywróże o co ci chodzi. Piszę już kilka lat z użyciem różnych CDI ale twoje pytania i problemy są zupełnie oderwane od rzeczywistości ;]
0

Ty robisz robisz jakiś prywatny projekt dla mercedesa za $$$$$$, że tak się boisz cały pokazać. Idź ty w ch..e do wróżki.
To tak jakbym napisał np.:
Działa mi:
Interface interfejs = () -> Klasa.metoda();
,a nie działa:
Interface interfejs = klasa::metoda;
,ale muszę mieć poprzez referencję bo tak mi wujek Sam nakazał, a kodu motyla noga nie pokażę bo nie....

R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

Nie prezentuje tu całego kodu, ponieważ nie miało by to sensu i zaciemniło by to tylko całą sytuacje. W skrócie chodzi o to, że w metodzie Main mogę pobierać za pomocą Guice z kontenera proste komponenty, a ten rozbudowany (Posiadający jako atrybut listę obiektów) zgłasza błąd bindowania.

Niestety nie wiem jak można doprowadzić do sytuacji, w której implementacja klasy CarShop będzie wstrzyknięta do listy carShops z klasy Operator. To jest chyba główny problem, z którym w przeciwieństwie do Springa, Guice nie może sobie poradzić.

R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

Shalom, Problem, który teraz chcę rozwiązać to wstrzyknięcie listy carShop bez jest inicjalizacji.
Kod który teraz działa:

Kopiuj
public class Operator implements IOperator {

	private List<CarShop> carShops = new ArrayList<CarShop>();

	public List<CarShop> getCarShops() {
		return carShops;
	}
	@Inject
	public Operator(CarShop carshop){
		this.carShops.add(carshop);
	}
}

Kod, który chcę, żeby zadziałał:

Kopiuj

public class Operator implements IOperator {

	private List<CarShop> carShops;

	public List<CarShop> getCarShops() {
		return carShops;
	}

	@Inject
	public void setCarShop(List<CarShop> carShops) {
		this.carShops = carShops;
	}
}

To drugie rozwiązanie działa w Springu. Tutaj prawdopodobnie też można takie coś uruchomić, ale trzeba w jakiś sposób zbindować listę w klasie modułu. Sęk w tym, że nie mam już pomysłu jak to można zrobić.

edytowany 1x, ostatnio: ralf2005
jarekczek
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Siemianowice Śląskie
  • Postów:500
0

@ralf2005, napisz (ale nie w formie komentarza, bo te są na off-topic, tylko jako post): Co chcesz osiągnąć?

  1. Chcesz mieć kilka implementacji CarShop i chcesz żeby Ci je wszystkie automatycznie wyłapał i wrzucił do listy?

  2. Chcesz utworzyć listę obiektów typu CarShop i ją wstrzykiwać?

Ad. 1. Shalom odpowiedział.

Ad. 2. Utwórz nowy typ CarShopList i jego wstrzykniesz bez problemu.


Przeważnie ignoruję niezarejestrowanych użytkowników.
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@ralf2005: ale co dokładnie wg ciebie Spring tam robi? Bo na moje oko to on ci wstrzykuje tam pustą listę zwyczajnie i to zupłnie przypadkiem na dobrą sprawę, bo ten mechanizm nie do tego służy. Czy mam racje? Ty chcesz tam dostać pustą listę? :D


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
R2
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 7 lat
  • Postów:14
0

Shalom, Z tego co widzę na debugu, to Spring ładuje jeden obiekt CarShop do listy carShops w klasie Operator. Właśnie to chcę osiagnąć w frameworku Guice. Żeby do listy carShops w klasie Operator Guice załadował instancje klasy CarShop.

Jareczek, Dokładnie tak jak punkt 2, chcę utworzyć listę obiektów i ją wstrzyknąć. Spróbuje zrobić tak jak napisałeś. Jednak mógłbyś mi powiedzieć, czy będe musiał to w jakiś sposób bindować?

jarekczek
  • Rejestracja:prawie 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Siemianowice Śląskie
  • Postów:500
0

Ja nie znam Guice'a i nie wiem, jak się binduje. W Springu zrobiłbym tak:

@Named
public CarShopList carShopList()
{
  CarShopList cs = new CarShopList();
  cs.getList().add(...)
  return cs;
}

No i wtedy lista wskoczy tutaj:

@Inject private CarShopList cs;

Przeważnie ignoruję niezarejestrowanych użytkowników.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.