Can't cast Element to StreamVolume #299
Labels
No labels
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
java
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
java-gi/java-gi#299
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
I want to retrieve a GstElement from my pipeline that implements GstStreamVolume.
I use the following code:
If I run my program, the cast fails with:
According to the Gstreamer docs I should be able to use it like that.
The element is also successfully retrieved.
Could this be the same issue as #295, that GstAudio hasn't been initialized?
In other words, did you try calling
GstAudio.javagi$ensureInitialized();before using the GstStreamVolume interface?Thanks for the reply.
I don't think that this is the issue.
I added
GstAudio.javagi$ensureInitialized();to my main class and thisfixes #295. I can successfully retrieve the element.
As the log shows, this is a casting exception not a NullPointerException.
For testing I also added all the gestreamer intializer:
This doesn't help.
I found how to fix this.
I can't cast to the Interface so I have to create a new
StreamVolume.StreamVolume$Implobject like so:Maybe I should write some documentation for this.
Yes that will work. But it’s a workaround and shouldn’t be necessary. I suspect that there’s a bug related to GstElement being an abstract class. I’ll have to investigate a bit further.
OK I found the cause.
The element that is returned by
pipeline.getByInterface(StreamVolume.getType())is of a type that isn't publicly documented in the GObject-Introspection data; basically a "private class". Java-GI tries to wrap that into a Java proxy class. Because the exact type isn't registered, I have to return a supertype: either a parent class or an implemented interface. Java's static typing doesn't allow instances of "unknown class that extends X and implements Y". It has to be a concrete Java class, but which one should it be? I haven't been able to come up with a foolproof solution yet.Currently I implemented this:
I frankly don't know how to properly resolve this. If I prioritize the implemented interfaces instead of the superclass, then other functions could break instead.
One other thing that complicates this issue: The return type of
getByInterface()isElement. But theStreamVolumeinterface can be applied to any GObject-derived class. So I cannot changegetByInterface()to return aStreamVolumeinstance; it would not be anElementand it would throw a ClassCastException, just like you saw when you tried to cast it in your own code.Of course, the actual object that
getByInterface()returns, IS most probably anElementsubclass that implementsStreamVolume. It's just not a type that java-gi knows about, so there is no wrapper class available on the Java side.I'm afraid I can't fix this issue cleanly. The only way to handle this, is like you already mentioned: