You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@flink.apache.org by Theodor Wübker <th...@inside-m2m.de> on 2022/11/14 08:38:03 UTC

Class loading in PbFormatUtils.getDescriptor

Hey everyone,

there is some use of reflection in PbFormatUtils.getDescriptor: Namely they get the Threads ClassLoader to load a protobuf-generated class. First of all, this appears to be a bad practice in general (refer first answer in this stackoverflow <https://stackoverflow.com/questions/1771679/difference-between-threads-context-class-loader-and-normal-classloader>). Secondly, this comes with a Drawback for me: If I generate the Java classes from Protobuf at runtime, they are not on the class path and not by default available for the Threads ClassLoader. This can be overcome using a hack like this, that sets the ClassLoader for the Current Thread to an URLClassLoader (which can be created at runtime and is then able to find the generated classes):
URLClassLoader newLoader = URLClassLoader.newInstance(new URL[] {urlToProtoClasses}, this.getClass().getClassLoader())
Thread.currentThread().setContextClassLoader(newLoader);
However this is not a great practice either. It will probably not even work, once there are multiple different Threads invoking PbFormatUtils.getDescriptor. Maybe there should be a way to set the ClassLoader for PbFormatUtils? 
If anyone knows a different solution to add the generated classes to the classpath please let me know!

-Theo

Re: Class loading in PbFormatUtils.getDescriptor

Posted by Martijn Visser <ma...@apache.org>.
Hi Theo,

Disclaimer: I work for Immerok

When we were working on a recipe for processing Protobuf [1], we used the
protoc-jar-maven-plugin and build-helper-maven-plugin to generate the
classes and add them to the classpath. Perhaps that would also help you.

Best regards,

Martijn

[1]
https://docs.immerok.cloud/docs/how-to-guides/development/reading-google-protobuf-with-apache-flink/

On Mon, Nov 14, 2022 at 9:39 AM Theodor Wübker <th...@inside-m2m.de>
wrote:

> Hey everyone,
>
> there is some use of reflection in PbFormatUtils.getDescriptor: Namely
> they get the Threads ClassLoader to load a protobuf-generated class. First
> of all, this appears to be a bad practice in general (refer first answer in this
> stackoverflow
> <https://stackoverflow.com/questions/1771679/difference-between-threads-context-class-loader-and-normal-classloader>).
> Secondly, this comes with a Drawback for me: If I generate the Java classes
> from Protobuf at runtime, they are not on the class path and not by default
> available for the Threads ClassLoader. This can be overcome using a hack
> like this, that sets the ClassLoader for the Current Thread to an
> URLClassLoader (which can be created at runtime and is then able to find
> the generated classes):
>
> URLClassLoader newLoader = URLClassLoader.newInstance(new URL[] {urlToProtoClasses}, this.getClass().getClassLoader())
> Thread.currentThread().setContextClassLoader(newLoader);
>
> However this is not a great practice either. It will probably not even
> work, once there are multiple different Threads invoking
> PbFormatUtils.getDescriptor. Maybe there should be a way to set the
> ClassLoader for PbFormatUtils?
> If anyone knows a different solution to add the generated classes to the
> classpath please let me know!
>
> -Theo
>