dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
157 stars 44 forks source link

[jnigen] Failing to handle imports of gradle dependency #1639

Open stuartmorgan opened 1 month ago

stuartmorgan commented 1 month ago

I'm trying to set up an initial jnigen of the video_player_android plugin to incrementally convert the existing native implementation, and it can't seem to find any of the ExoPlayer (media3) code:

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/CustomSSLSocketFactory.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/Messages.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/QueuingEventSink.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerCallbacks.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerEventCallbacks.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerOptions.java...
Loading source file android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayerPlugin.java...
Constructing Javadoc information...
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:8: error: cannot find symbol
import androidx.media3.common.PlaybackException;
                             ^
  symbol:   class PlaybackException
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:9: error: cannot find symbol
import androidx.media3.common.Player;
                             ^
  symbol:   class Player
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:10: error: cannot find symbol
import androidx.media3.common.VideoSize;
                             ^
  symbol:   class VideoSize
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:11: error: cannot find symbol
import androidx.media3.exoplayer.ExoPlayer;
                                ^
  symbol:   class ExoPlayer
  location: package androidx.media3.exoplayer
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:13: error: package Player does not exist
final class ExoPlayerEventListener implements Player.Listener {
                                                    ^
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:14: error: cannot find symbol
  private final ExoPlayer exoPlayer;
                ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.ExoPlayerEventListener
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:19: error: cannot find symbol
  ExoPlayerEventListener(ExoPlayer exoPlayer, VideoPlayerCallbacks events) {
                         ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.ExoPlayerEventListener
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:23: error: cannot find symbol
  ExoPlayerEventListener(ExoPlayer exoPlayer, VideoPlayerCallbacks events, boolean initialized) {
                         ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.ExoPlayerEventListener
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerEventListener.java:91: error: cannot find symbol
  public void onPlayerError(@NonNull final PlaybackException error) {
                                           ^
  symbol:   class PlaybackException
  location: class io.flutter.plugins.videoplayer.ExoPlayerEventListener
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java:7: error: cannot find symbol
import androidx.media3.common.PlaybackParameters;
                             ^
  symbol:   class PlaybackParameters
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java:8: error: cannot find symbol
import androidx.media3.exoplayer.ExoPlayer;
                                ^
  symbol:   class ExoPlayer
  location: package androidx.media3.exoplayer
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java:27: error: cannot find symbol
  static ExoPlayerState save(ExoPlayer exoPlayer) {
                             ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.ExoPlayerState
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java:36: error: cannot find symbol
      long position, int repeatMode, float volume, PlaybackParameters playbackParameters) {
                                                   ^
  symbol:   class PlaybackParameters
  location: class io.flutter.plugins.videoplayer.ExoPlayerState
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java:53: error: cannot find symbol
  private final PlaybackParameters playbackParameters;
                ^
  symbol:   class PlaybackParameters
  location: class io.flutter.plugins.videoplayer.ExoPlayerState
android/src/main/java/io/flutter/plugins/videoplayer/ExoPlayerState.java:63: error: cannot find symbol
  void restore(ExoPlayer exoPlayer) {
               ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.ExoPlayerState
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:12: error: cannot find symbol
import androidx.media3.common.MediaItem;
                             ^
  symbol:   class MediaItem
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:13: error: cannot find symbol
import androidx.media3.common.MimeTypes;
                             ^
  symbol:   class MimeTypes
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:14: error: package androidx.media3.common.util does not exist
import androidx.media3.common.util.UnstableApi;
                                  ^
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:15: error: cannot find symbol
import androidx.media3.datasource.DataSource;
                                 ^
  symbol:   class DataSource
  location: package androidx.media3.datasource
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:16: error: cannot find symbol
import androidx.media3.datasource.DefaultDataSource;
                                 ^
  symbol:   class DefaultDataSource
  location: package androidx.media3.datasource
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:17: error: cannot find symbol
import androidx.media3.datasource.DefaultHttpDataSource;
                                 ^
  symbol:   class DefaultHttpDataSource
  location: package androidx.media3.datasource
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:18: error: package androidx.media3.exoplayer.source does not exist
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
                                       ^
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:19: error: package androidx.media3.exoplayer.source does not exist
import androidx.media3.exoplayer.source.MediaSource;
                                       ^
android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java:10: error: cannot find symbol
import androidx.media3.common.MediaItem;
                             ^
  symbol:   class MediaItem
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java:11: error: package androidx.media3.exoplayer.source does not exist
import androidx.media3.exoplayer.source.MediaSource;
                                       ^
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:40: error: cannot find symbol
  MediaItem getMediaItem() {
  ^
  symbol:   class MediaItem
  location: class io.flutter.plugins.videoplayer.HttpVideoAsset
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:61: error: package MediaSource does not exist
  MediaSource.Factory getMediaSourceFactory(Context context) {
             ^
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:76: error: package DefaultHttpDataSource does not exist
      Context context, DefaultHttpDataSource.Factory initialFactory) {
                                            ^
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:75: error: package MediaSource does not exist
  MediaSource.Factory getMediaSourceFactory(
             ^
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:89: error: package DefaultHttpDataSource does not exist
      @NonNull DefaultHttpDataSource.Factory factory,
                                    ^
android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java:73: error: cannot find symbol
  abstract MediaItem getMediaItem();
           ^
  symbol:   class MediaItem
  location: class io.flutter.plugins.videoplayer.VideoAsset
android/src/main/java/io/flutter/plugins/videoplayer/VideoAsset.java:81: error: package MediaSource does not exist
  abstract MediaSource.Factory getMediaSourceFactory(Context context);
                      ^
android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java:9: error: cannot find symbol
import androidx.media3.common.MediaItem;
                             ^
  symbol:   class MediaItem
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java:10: error: package androidx.media3.exoplayer.source does not exist
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory;
                                       ^
android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java:11: error: package androidx.media3.exoplayer.source does not exist
import androidx.media3.exoplayer.source.MediaSource;
                                       ^
android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java:20: error: cannot find symbol
  MediaItem getMediaItem() {
  ^
  symbol:   class MediaItem
  location: class io.flutter.plugins.videoplayer.LocalVideoAsset
android/src/main/java/io/flutter/plugins/videoplayer/LocalVideoAsset.java:25: error: package MediaSource does not exist
  MediaSource.Factory getMediaSourceFactory(Context context) {
             ^
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:10: error: cannot find symbol
import androidx.media3.common.MediaItem;
                             ^
  symbol:   class MediaItem
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:11: error: package androidx.media3.common.util does not exist
import androidx.media3.common.util.UnstableApi;
                                  ^
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:12: error: cannot find symbol
import androidx.media3.exoplayer.rtsp.RtspMediaSource;
                                     ^
  symbol:   class RtspMediaSource
  location: package androidx.media3.exoplayer.rtsp
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:13: error: package androidx.media3.exoplayer.source does not exist
import androidx.media3.exoplayer.source.MediaSource;
                                       ^
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:22: error: cannot find symbol
  MediaItem getMediaItem() {
  ^
  symbol:   class MediaItem
  location: class io.flutter.plugins.videoplayer.RtspVideoAsset
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:29: error: package MediaSource does not exist
  MediaSource.Factory getMediaSourceFactory(Context context) {
             ^
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:7: error: cannot find symbol
import static androidx.media3.common.Player.REPEAT_MODE_ALL;
                                    ^
  symbol:   class Player
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:7: error: static import only from classes and interfaces
import static androidx.media3.common.Player.REPEAT_MODE_ALL;
^
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:8: error: cannot find symbol
import static androidx.media3.common.Player.REPEAT_MODE_OFF;
                                    ^
  symbol:   class Player
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:8: error: static import only from classes and interfaces
import static androidx.media3.common.Player.REPEAT_MODE_OFF;
^
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:15: error: cannot find symbol
import androidx.media3.common.AudioAttributes;
                             ^
  symbol:   class AudioAttributes
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:16: error: cannot find symbol
import androidx.media3.common.C;
                             ^
  symbol:   class C
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:17: error: cannot find symbol
import androidx.media3.common.MediaItem;
                             ^
  symbol:   class MediaItem
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:18: error: cannot find symbol
import androidx.media3.common.PlaybackParameters;
                             ^
  symbol:   class PlaybackParameters
  location: package androidx.media3.common
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:19: error: cannot find symbol
import androidx.media3.exoplayer.ExoPlayer;
                                ^
  symbol:   class ExoPlayer
  location: package androidx.media3.exoplayer
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:24: error: cannot find symbol
  @NonNull private final MediaItem mediaItem;
                         ^
  symbol:   class MediaItem
  location: class io.flutter.plugins.videoplayer.VideoPlayer
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:28: error: cannot find symbol
  @NonNull private ExoPlayer exoPlayer;
                   ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.VideoPlayer
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:76: error: cannot find symbol
      @NonNull MediaItem mediaItem,
               ^
  symbol:   class MediaItem
  location: class io.flutter.plugins.videoplayer.VideoPlayer
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:105: error: cannot find symbol
  private ExoPlayer createVideoPlayer() {
          ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.VideoPlayer
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:123: error: cannot find symbol
  private static void setAudioAttributes(ExoPlayer exoPlayer, boolean isMixMode) {
                                         ^
  symbol:   class ExoPlayer
  location: class io.flutter.plugins.videoplayer.VideoPlayer
android/src/main/java/io/flutter/plugins/videoplayer/VideoPlayer.java:68: error: cannot find symbol
    ExoPlayer get();
    ^
  symbol:   class ExoPlayer
  location: interface io.flutter.plugins.videoplayer.VideoPlayer.ExoPlayerProvider
android/src/main/java/io/flutter/plugins/videoplayer/HttpVideoAsset.java:87: error: cannot find symbol
  @OptIn(markerClass = UnstableApi.class)
                       ^
  symbol:   class UnstableApi
  location: class io.flutter.plugins.videoplayer.HttpVideoAsset
android/src/main/java/io/flutter/plugins/videoplayer/RtspVideoAsset.java:27: error: cannot find symbol
  @OptIn(markerClass = UnstableApi.class)
                       ^
  symbol:   class UnstableApi
  location: class io.flutter.plugins.videoplayer.RtspVideoAsset
Note: 60 errors
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.util.Map.size()" because "<parameter1>" is null
    at java.base/java.util.HashMap.putMapEntries(Unknown Source)
    at java.base/java.util.HashMap.putAll(Unknown Source)
    at com.github.dart_lang.jnigen.apisummarizer.Main.main(Main.java:132)

Fatal: Cannot generate summary: FormatException: Unexpected end of input (at character 1)

This is running in the plugin, after doing the example app built, the plugin depends on androidx.media3:media3-exoplayer via gradle, and my config includes add_gradle_deps: true, so I would expect it to find these symbols.

It's not clear to me why it's not, or what my next step as a user would be here.

HosseinYousefi commented 1 month ago

I would encourage you to use the bytecode .jar of exoplayer instead of .java sources. The doclet parser used to parse Java sources does not work with "incomplete" sources. The only reason I didn't remove it yet is because it is useful for adding documentation and parameter names to the generated bindings.

I plan to parse the javadoc jar and extract the docs from that instead, once that's done I'll remove the source parser altogether: https://github.com/dart-lang/native/issues/1079

In the meantime it's useful to improve the error messages here.

stuartmorgan commented 1 month ago

I would encourage you to use the bytecode .jar of exoplayer instead of .java sources.

How? I'm not intentionally using either, I'm just pointing to my plug-in source and requesting auto-addition of its build dependencies, following this example.

Am I responsible for manually configuring the import of all dependencies in this scenario? I thought that's what the example/ build was supposed to do for me.

HosseinYousefi commented 1 month ago

You can add the exoplayer dependency to the app/build.gradle of your example like https://github.com/dart-lang/http/blob/master/pkgs/cronet_http/example/android/app/build.gradle#L75-L78

build the example app using flutter build apk for gradle to download and cache the dependencies. And only fill in classes:. No need to add any source_path.

Am I responsible for manually configuring the import of all dependencies in this scenario? I thought that's what the example/ build was supposed to do for me.

The two parsers – doclet for source, and ASM for bytecode unfortunately do not complete one another. The source should be complete in order for doclet to work and that is one of the reasons I plan on removing it completely.

stuartmorgan commented 1 month ago

You can add the exoplayer dependency to the app/build.gradle of your example

Is there an issue tracking the need to duplicate all dependency information from a plugin into the example app just for jnigen?

No need to add any source_path.

Should I file a new issue about the fact that the example that the README points to for exactly my scenario is using source_path?

HosseinYousefi commented 1 month ago

Is there an issue tracking the need to duplicate all dependency information from a plugin into the example app just for jnigen?

There is an umbrella issue which includes this: https://github.com/dart-lang/native/issues/793#issuecomment-2118525810

Should I file a new issue about the fact that the example that the README points to for exactly my scenario is using source_path?

I can use this issue for that, thank you.