I have been trying to follow this tutorial: https://dagger.dev/tutorial
But I have found several problems with it. The first problems occurs in the section https://dagger.dev/tutorial/01-setup, here we have the following code:
Status unused = commandRouter.route(scanner.nextLine());
}
This makes no sense because the CommandRouter.route() method returns a result:
private final Map<String, Command> commands = Collections.emptyMap();
Result route(String input) {
Not a Status object. I just removed the Status unused and continued.
Now I am trying to follow the instructions on this section: https://dagger.dev/tutorial/10-deposit-after-login
but I keep getting an error here:
DepositCommand(Database.Account account, Outputter outputter) {
this.account = account;
this.outputter = outputter;
}
This code does not compile with the error constructor
BigDecimalCommand in class org.example.BigDecimalCommand cannot be applied to given types;
[ERROR] required: org.example.Outputter
[ERROR] found: no arguments
[ERROR] reason: actual and formal argument lists differ in length
Now the DepositCommand class extends from BigDecimalCommand:
final class DepositCommand extends BigDecimalCommand {
private final Database.Account account;
private final Outputter outputter;
@Inject
DepositCommand(Database.Account account, Outputter outputter) {
this.account = account;
this.outputter = outputter;
}
@Override
public void handleAmount(BigDecimal amount) {
account.deposit(amount);
outputter.output(account.username() + " now has: " + account.balance());
}
}
And the BigDecimalCommand class has only one constructor argument:
abstract class BigDecimalCommand extends SingleArgCommand {
private final Outputter outputter;
protected BigDecimalCommand(Outputter outputter) {
this.outputter = outputter;
}
Has anyone else here faced the same issues with the tutorial?
For BigDecimalCommand to act as the superclass of DepositCommand, you have to call its constructor using the super
keyword as the first line of each of your constructors. A reference to a 0-arg constructor is added by default if you don't specify one; here it's trying to call BigDecimalCommand()
, which does not exist.
The tutorial text is missing the explicit super
call, but it appears correctly in the version of DepositCommand that is checked in (comment is mine):
@Inject
DepositCommand(Outputter outputter, Account account, WithdrawalLimiter withdrawalLimiter) {
super(outputter);
// ^^^^^^^^^^^^^^^^^
this.outputter = outputter;
this.account = account;
this.withdrawalLimiter = withdrawalLimiter;
}
As a result, in the version you see checked in, there are two separate outputter
fields: one in BigDecimalCommand and one in DepositCommand. It's not wrong, but personally I might have chosen to make the BigDecimalCommand outputter
field protected
so I could refer toit from DepositCommand
without having to save it separately.