Problem z konfiguracją frameworka Google Guice

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:

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

0

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

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.

0

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


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

0

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

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:

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

(albo spring)

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

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."

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...

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
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ą:

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

Jest zgłaszany błąd Bindingu.

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

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

W przypadku skorzystania z

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

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

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

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.

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....

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ć.

0

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

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ł:


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ć.

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.

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

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ć?

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;

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