Maciek Murawski
Maciek Murawski

Reputation: 444

Compilation error while running code with RxJava

I'm new to RxJava so forgive me all my newbie mistakes ;)

I have following code:

Observable
            .fromIterable( observables )
            .flatMap(task -> task.observeOn(Schedulers.computation()))
            // wait for all tasks to finish
            .lastOrError()
            .flattenAsObservable( x -> someWeirdMapWithObject.values())
            .cast(BrandBuilder.class)
            .map( brandBuilder -> brandBuilder.build() )

observables is a list of Observables which will write data to someWeirdMapWithObject. As name suggest someWeirdMapWithObject has Object as values.

Strange thing is that in Intellij IDEA this snippet will do fine, no errors, no warnings (except one - brandBuilder.build() can be inlined). But when I try to compile this code, it gets compilation error:

error: cannot find symbol
                .map( brandBuilder -> brandBuilder.build() )
                                                  ^
  symbol:   method build()
  location: variable brandBuilder of type Object

When I change last line to:

.map( brandBuilder -> ((BrandBuilder) brandBuilder).build() )

it's all good.

My questions are:

Thanks in advance for response ;)

EDIT

Better example below (as Junit Test, I've noticed that when I make observables of same type this code will compile otherwise it won't):

@Test
public void test() throws Exception {
    Observable<String> first = Observable.fromCallable(() -> "HEY").delay(250, TimeUnit.MILLISECONDS);
    Observable<Integer> second = Observable.fromCallable(() -> 1).delay(350, TimeUnit.MILLISECONDS);
    List<Observable> observables = com.google.common.collect.Lists.newArrayList(first, second);
    Map<Long, Object> someWeirdMapWithObject = com.google.common.collect.ImmutableMap.of(
            1L, new BrandBuilder(1),
            2L, new BrandBuilder(2)
    );
    Observable
            .fromIterable(observables)
            .flatMap(task -> task.observeOn(Schedulers.computation()))
            // wait for all tasks to finish
            .lastOrError()
            .flattenAsObservable(x -> someWeirdMapWithObject.values())
            .cast(BrandBuilder.class)
            .map(BrandBuilder::build)
            .toList().blockingGet();
}

class BrandBuilder{
    private int bar;
    BrandBuilder(int bar) {
        this.bar = bar;
    }
    public Brand build(){
        return new Brand(this.bar);
    }
}

class Brand{
    private int bar;
    Brand(int bar) {
        this.bar = bar;
    }
}

Upvotes: 0

Views: 65

Answers (1)

akarnokd
akarnokd

Reputation: 69997

The problem seems to come from the raw type in this declaration:

List<Observable> observables =
    com.google.common.collect.Lists.newArrayList(first, second);

This seems to throw off javac in the flow below and prevent generics/inference from working properly. Use

List<Observable<?>> observables =
   com.google.common.collect.Lists.newArrayList(first, second);

instead and everything below should compile.

For me, Eclipse latest did indicate problems in the editor, highlighting the ::build part so I guess IntelliJ not reporting the error could be a bug there.

Upvotes: 1

Related Questions