Mejores prácticas para crear aplicaciones de flujo Spark de Java

Consejos y mejores prácticas para configurar proyectos de creación de Java en Data Flow.

Maven se utiliza en los siguientes ejemplos para mostrar las distintas posibilidades de configuración.

Utilice una versión consistente de Spark en las bibliotecas y en Data Flow
La forma más sencilla de hacerlo es definir una variable común y reutilizarla. En el siguiente ejemplo, la variable común se denomina spark.version.
<properties>
 ...
 <spark.version>3.0.2</spark.version>
 ...
</properties>
<dependencies>
 <dependency>
     <groupId>org.apache.spark</groupId>
     <artifactId>spark-core_2.12</artifactId>
     <version>${spark.version}</version>
     <scope>provided</scope>
 </dependency>
Nota

Asegúrese de que la versión de Scala en artifactId sea adecuada para la versión de Spark. En el ejemplo, artifactId está definido en spark-core_2.12 para Scala 2.12.
Incluya los binarios de Spark que ya forman parte del paquete de Spark estándar con el scope provided para evitar cualquier duplicación de código.
Ampliando el ejemplo anterior:
<properties>
 ...
 <spark.version>3.0.2</spark.version>
 ...
</properties>
<dependencies>
 <dependency>
     <groupId>org.apache.spark</groupId>
     <artifactId>spark-core_2.12</artifactId>
     <version>${spark.version}</version>
     <scope>provided</scope>
 </dependency>
 <dependency>
     <groupId>org.apache.spark</groupId>
     <artifactId>spark-sql_2.12</artifactId>
     <version>${spark.version}</version>
     <scope>provided</scope>
 </dependency>
...
Nota

Puede encontrar más información sobre el ámbito de dependencia en la documentación de Maven.
Paquete de binarios de Spark que no forman parte del paquete estándar con la aplicación Spark.
En este ejemplo se incluye spark-sql-kafka-0-10_2.12 en artifactId.
<properties>
 ...
 <spark.version>3.0.2</spark.version>
 ...
</properties>
<dependencies>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql-kafka-0-10_2.12</artifactId>
    <version>${spark.version}</version>
</dependency>
...
El SDK de Oracle Cloud Infrastructure puede compilarse en una versión diferente de bibliotecas de terceros, lo que puede provocar fallos de tiempo de ejecución. Para evitar estos fallos, empaquete el SDK de Oracle Cloud Infrastructure y las bibliotecas de terceros con la aplicación Spark y mueva las bibliotecas de terceros más recientes a un espacio de nombres sombreado.
Por ejemplo:
<dependencies>
    <dependency>
        <groupId>com.oracle.oci.sdk</groupId>
        <artifactId>
</artifactId>
        <optional>false</optional>
        <version>1.36.1</version>
    </dependency>
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.11.1</version>
    </dependency>
</dependencies>
...
<build>
 <plugins>
 ...
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-shade-plugin</artifactId>
   <version>3.2.4</version>
   <configuration>
       <!-- The final uber jar file name will not have a version component. -->
       <finalName>${project.artifactId}</finalName>
       <createDependencyReducedPom>false</createDependencyReducedPom>
       <transformers>
           <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
           <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
       </transformers>
       <relocations>
           <relocation>
               <pattern>com.google.</pattern>
               <shadedPattern>com.shaded.google.</shadedPattern>
           </relocation>
           <relocation>
               <pattern>com.oracle.bmc.</pattern>
               <shadedPattern>com.shaded.oracle.bmc.</shadedPattern>
           </relocation>
       </relocations>
       <!-- exclude signed Manifests -->
       <filters>
           <filter>
               <artifact>*:*</artifact>
               <excludes>
                   <exclude>META-INF/*.SF</exclude>
                   <exclude>META-INF/*.DSA</exclude>
                   <exclude>META-INF/*.RSA</exclude>
               </excludes>
           </filter>
       </filters>
   </configuration>
   <executions>
       <execution>
           <phase>package</phase>
           <goals>
               <goal>shade</goal>
           </goals>
       </execution>
   </executions>
</plugin>
...
Archivo POM.xml de ejemplo para la aplicación de flujo de Spark de Java

POM.xml de ejemplo que se utiliza al crear una aplicación de flujo de Spark basada en Java para su uso con Data Flow.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>StructuredKafkaWordCount</artifactId>
    <version>1.0.0-SNAPSHOT</version>
 
    <properties>
      <spark.version>3.2.1</spark.version>
      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>com.oracle.oci.sdk</groupId>
            <artifactId>oci-java-sdk-addons-sasl</artifactId>
            <optional>false</optional>
            <version>1.36.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.11.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.12</artifactId>
            <version>${spark.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.12</artifactId>
            <version>${spark.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql-kafka-0-10_2.12/3.2.1</artifactId>
            <version>${spark.version}</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <skipAssembly>false</skipAssembly>
                </configuration>
            </plugin>
 
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <configuration>
                    <!-- The final uber jar file name will not have a version component. -->
                    <finalName>${project.artifactId}</finalName>
                    <createDependencyReducedPom>false</createDependencyReducedPom>
                    <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"/>
                    </transformers>
                    <relocations>
                        <relocation>
                            <pattern>com.google.</pattern>
                            <shadedPattern>com.shaded.google.</shadedPattern>
                        </relocation>
                        <relocation>
                            <pattern>com.oracle.bmc.</pattern>
                            <shadedPattern>com.shaded.oracle.bmc.</shadedPattern>
                        </relocation>
                    </relocations>
                    <!-- exclude signed Manifests -->
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                            </excludes>
                        </filter>
                    </filters>
                </configuration>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
 
        </plugins>
    </build>
</project>