Kotlin and Android Development featuring Jetpack: Error in generated Game.java (page 136)

I’m under the impression that when the reader gets to page 136 (“View Data with the Database Inspector”), the code SHOULD be able to build without errors.

Reasons for the assumption:

  • The Database Inspector ISN’T appearing (as far as I can tell, in Arctic Fox, it was moved to the “App Inspection” tab and no longer exists as a Tool window of its own).

  • I assume the act of successfully building and running the app is what creates and populates the database on the emulator, and…

  • once that database exists, Android Studio notices it & reveals the Database Inspector functionality.

There are no visible errors in the sourcecode itself (no red squiggly lines in any editable source files, no red marks along the right margin), but I’m getting a slew of errors in the generated app/build/tmp/kapt3/stubs/debug/dev/mfazio/pennydrop/data/Game.java class, PennyDropDao.java, and Player.java (note: all are *.java and presumably generated, the *.kt files seem to be fine) that I’m not sure how to troubleshoot:

C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:7: warning: There are multiple good constructors and Room will pick the no-arg constructor. You can use the @Ignore annotation to eliminate unwanted constructors.
public final class Game {
             ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:11: error: Cannot find setter for field.
    private final dev.mfazio.pennydrop.data.GameState gameState = null;
                                                      ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:13: error: Cannot find setter for field.
    private final java.time.OffsetDateTime startTime = null;
                                           ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:15: error: Cannot find setter for field.
    private final java.time.OffsetDateTime endTime = null;
                                           ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:17: error: Cannot find setter for field.
    private final java.util.List<java.lang.Integer> filledSlots = null;
                                                    ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:19: error: Cannot find setter for field.
    private final java.lang.Integer lastRoll = null;
                                    ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:21: error: Cannot find setter for field.
    private final java.lang.String currentTurnText = null;
                                   ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:22: error: Cannot find setter for field.
    private final boolean canRoll = false;
                          ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:23: error: Cannot find setter for field.
    private final boolean canPass = false;
                          ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:7: warning: There are multiple good constructors and Room will pick the no-arg constructor. You can use the @Ignore annotation to eliminate unwanted constructors.
public final class Game {
             ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:11: error: Cannot find setter for field.
    private final dev.mfazio.pennydrop.data.GameState gameState = null;
                                                      ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:13: error: Cannot find setter for field.
    private final java.time.OffsetDateTime startTime = null;
                                           ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:15: error: Cannot find setter for field.
    private final java.time.OffsetDateTime endTime = null;
                                           ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:17: error: Cannot find setter for field.
    private final java.util.List<java.lang.Integer> filledSlots = null;
                                                    ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:19: error: Cannot find setter for field.
    private final java.lang.Integer lastRoll = null;
                                    ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:21: error: Cannot find setter for field.
    private final java.lang.String currentTurnText = null;
                                   ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:22: error: Cannot find setter for field.
    private final boolean canRoll = false;
                          ^
C:\src\experiments\android\PennyDrop\app\build\tmp\kapt3\stubs\debug\dev\mfazio\pennydrop\data\Game.java:23: error: Cannot find setter for field.
    private final boolean canPass = false;
                          

Any idea which class to even start looking at to figure out what’s wrong? I’m guessing I forgot an annotation somewhere… or possibly, in an attempt to fix an earlier typo problem by copying files from the .zip file, might have created a bigger one by prematurely copying something mentioned later in the chapter that’s now triggering the error above by expecting the presence of something that officially hasn’t been added yet as of page 136.

For what it’s worth, it looks like the following methods of PennyDropDao.kt haven’t yet been mentioned as of page 136, but are in the .zip file’s version, and the references to them by the lines added prior to page 136 will generate errors in PennyDropDao.kt itself unless they’re added:

getPlayer()
insertGame()
insertPlayer()
insertPlayers()
updateGame()

According to WinMerge, my versions of Converters.kt, Game.kt, GameState.kt, GameStatus.kt, PennyDropDatabase.kt, and PennyDropRepository.kt are presently identical to the versions in the zipfile.

As far as I can recall, my copy of PennyDropDao.kt was identical, until I commented the methods out, then went through chapter 5 from the start and moved the methods from inside the comment block to the outside in the order they’re mentioned in the chapter. That’s how I noticed that 5 methods listed above were referenced by the code, but not mentioned yet as of page 136… they were still in the comment block as of page 136.

Hey Jeff,
I’m looking through what you have here and I’m trying to figure out what’s going on.

The first thing I want to hit are those five functions from PennyDropDao. All five are on pages 118 and 119 when we first create the abstract class. Are these the functions you’re referencing here?

The issue with the Game class looks familiar from my initial development work, though I do not remember what caused that specific problem. Could you share what your Game class looks like? And an offer: if you wanted to upload your work to GitHub or something similar, I’d be willing to troubleshoot things that way with you. I want to make sure you can get as much as possible out of the book.

For reference, you’re right on point with the *.java files being generated. :+1: Also, you’re correct on the Database Inspector being moved in Arctic Fox. I’m really starting to dislike this new Android Studio update.

Let me know on your Game class (and if you want to put the whole project out somewhere I can access it) and we’ll go from there!

1 Like

Ok, I created a private repository at https://github.com/jskubick/pennydrop and added you (MFazio23) as a collaborator. It’s a snapshot of what I have as of page 136, and for the most part it used the snapshot of chapter 4 from the zipfile as its starting point, plus the fixes to the game’s logic I made a few days ago (before realizing it was supposed to have that bug at the end of chapter 4).

I apologize for the gratuitous use of semicolons. I tried to remove most of the ones I added (20 years of Java habits die hard), but I’m sure there are still a few I missed.

Yeah, the five methods are on pages 118-119. I guess I overlooked them when retracing my steps. I cleaned up PennyDropDao before uploading it to Github, so it should now match the copy in the zipfile.

Thanks for all your help! I really appreciate it!

Jeff, I think I got it. The book was written against Room 2.3.0-beta01 which doesn’t play nice with Kotlin 1.5.30. If you upgrade your Room dependency to 2.3.0, it should work without trouble.

Please let me know either way!

OK, that fixed it. Thanks!!!

1 Like

Hmmm… I might have spoken too soon. The compilation errors went away, but the database inspector itself seems to be semi-dead (or possibly, the database itself isn’t getting created).

How to replicate:

  1. In the emulator, go to Settings and uninstall PennyDrop to completely wipe the slate clean.

  2. Run it from Android Studio

  3. Click Players in the navigation bar, name the two human players “one” and “two”, then click the FAB to start the game.

  4. The game itself is dead at this point (as I think it’s supposed to be, since we haven’t re-bound the values to the UI yet), but if you go to App Inspection → Database Inspector, it says “Nothing to show” under “Databases”.

Prior to the above steps, I DID somehow manage to get it to create a database ONE TIME by running the app in debug mode with a breakpoint on PennyDropDao.startGame() and stepping through it until I hit ‘resume’ and the app crashed… but THAT database showed up as “disconnected”, and subsequent run attempts left it unchanged (closeOpenGames() never appeared to do anything, and no new records were inserted into the table).

Update: I also tried using room 2.4.0-alpha04 instead of 2.3.0. It didn’t make any difference, so I went back to 2.3.0.

Should I just use older versions of Room, Kotlin, and other plugins for now? If so, which ones?

The safest way to go ahead is to use the ones listed in the Gradle Dependencies appendix since those are what I used when writing the book. I can check later on Arctic Fox to see what it shows me for the Database Inspector and let you know what I find.

OK, I replaced both build.gradle files with the copies from chapter 5’s zipfile, replaced android-manifest.xml with the zipfile’s, deleted my day and night style.xml files that somehow ended up getting created along the way, and edited settings.gradle to comment-out the repositoriesMode.set() that was causing Arctic Fox to complain about redefined repositories.

Unfortunately, it’s still not working. I committed the changes to Github so you can see the exact state it’s in right now.

Update: I loaded the finished code for chapter 5 from the zipfile, and it appears to work, so it’s possible that I either accidentally omitted something from the beginning of chapter 5, or the “View Data with the Database Inspector” section was a few pages premature & depends upon something that comes a few pages later in order to work. I’m going to soldier on through the rest of chapter 5 now to see whether adding something from later in the chapter fixes the problem & let you know what happens.

OK, it looks like the remaining errors were all typos and my fault:

  • The call to PickPlayersFragment.findNavController().navigate(R.id.gameFragment) was in the wrong block

  • A chunk of GameViewModel was missing

  • Player.playerName was var, not val (probably didn’t matter)

I also incremented the database version to “2” and added a call to .fallbackToDestructiveMigration() to the database class’s builder call for good measure.

Onward, to Chapter 6 :slight_smile: