public void beforeAnalysis()

in core/src/main/java/com/google/cloud/sql/nativeimage/CloudSqlFeature.java [52:153]


  public void beforeAnalysis(BeforeAnalysisAccess access) {
    if (access.findClassByName(CLOUD_SQL_SOCKET_CLASS) == null) {
      return;
    }

    // The Core Cloud SQL Socket
    NativeImageUtils.registerClassForReflection(access, CLOUD_SQL_SOCKET_CLASS);

    // The JNDI DNS factory for looking up DNS names.
    NativeImageUtils.registerClassForReflection(access, JNDI_DNS_FACTORY);
    NativeImageUtils.registerClassForReflection(access, JNDI_DNS_OBJECT_FACTORY);

    // Register Hikari configs if used with Cloud SQL.
    if (access.findClassByName("com.zaxxer.hikari.HikariConfig") != null) {
      NativeImageUtils.registerClassForReflection(access, "com.zaxxer.hikari.HikariConfig");

      RuntimeReflection.register(
          access.findClassByName("[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;"));

      RuntimeReflection.register(access.findClassByName("[Ljava.sql.Statement;"));
    }

    // Register PostgreSQL driver config.
    if (access.findClassByName(POSTGRES_SOCKET_CLASS) != null) {
      NativeImageUtils.registerClassForReflection(
          access, "com.google.cloud.sql.postgres.SocketFactory");
      NativeImageUtils.registerClassForReflection(access, "org.postgresql.PGProperty");
    }

    // Register MySQL driver config.
    if (access.findClassByName(MYSQL_SOCKET_CLASS) != null) {
      NativeImageUtils.registerClassForReflection(access, MYSQL_SOCKET_CLASS);

      NativeImageUtils.registerClassForReflection(access, "com.mysql.jdbc.StandardSocketFactory");

      NativeImageUtils.registerConstructorsForReflection(
          access, "com.mysql.cj.conf.url.SingleConnectionUrl");

      // for mysql-j-5
      NativeImageUtils.registerConstructorsForReflection(
          access, "com.mysql.jdbc.log.StandardLogger");
      // for mysql-j-8
      NativeImageUtils.registerConstructorsForReflection(access, "com.mysql.cj.log.StandardLogger");

      Class<?> cjExceptionClass = access.findClassByName("com.mysql.cj.exceptions.CJException");
      if (cjExceptionClass != null) {
        // The CJException exists only jdbc/mysql-j-8 module's dependency
        access.registerSubtypeReachabilityHandler(
            (duringAccess, exceptionClass) ->
                NativeImageUtils.registerClassForReflection(duringAccess, exceptionClass.getName()),
            cjExceptionClass);
      }

      Class<?> mySqlNonTransientConnectionException =
          access.findClassByName(
              "com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException");
      if (mySqlNonTransientConnectionException != null) {
        NativeImageUtils.registerConstructorsForReflection(
            access, mySqlNonTransientConnectionException.getName());
      }

      Class<?> mySqlNonTransientException =
          access.findClassByName("com.mysql.jdbc.exceptions.MySQLNonTransientException");
      if (mySqlNonTransientException != null) {
        NativeImageUtils.registerConstructorsForReflection(
            access, mySqlNonTransientException.getName());
      }

      // JDBC classes create socket connections which must be initialized at run time.
      RuntimeClassInitialization.initializeAtRunTime("com.mysql.cj.jdbc");
    }
    // This Netty class should be initialized at runtime
    // https://github.com/netty/netty/issues/11638
    Class<?> bouncyCastleAlpnSslUtils =
        access.findClassByName("io.netty.handler.ssl.BouncyCastleAlpnSslUtils");
    if (bouncyCastleAlpnSslUtils != null) {
      RuntimeClassInitialization.initializeAtRunTime(bouncyCastleAlpnSslUtils);
    }
    if (access.findClassByName("jnr.ffi.provider.FFIProvider") != null) {

      // Disabling this as ASM (runtime code generation library) can sometimes cause issues during
      // native image build.
      String asmEnabledPropertyKey = "jnr.ffi.asm.enabled";
      if (System.getProperty(asmEnabledPropertyKey) == null) {
        System.setProperty(asmEnabledPropertyKey, String.valueOf(false));
      }

      NativeImageUtils.registerForReflectiveInstantiation(access, "jnr.ffi.provider.jffi.Provider");
      RuntimeClassInitialization.initializeAtBuildTime("jnr.ffi.provider.jffi.NativeLibraryLoader");

      // StubLoader loads the native stub library and is only intended to be called reflectively.
      // Note that this configuration only covers linux x86_64 platform at the moment.
      NativeImageUtils.registerClassForReflection(access, "com.kenai.jffi.internal.StubLoader");
      NativeImageUtils.registerClassForReflection(access, "com.kenai.jffi.Version");

      NativeImageUtils.registerClassForReflection(
          access, "jnr.ffi.provider.jffi.platform.x86_64.linux.TypeAliases");

      // Scan the jnr.constants.* packages and register all for reflection
      registerPackageForReflection(access, "jnr.constants");
    }
  }