Spring两次调用“ main”方法:在第二个Admin SDK服务器端身份验证时导致异常

时间:2018-08-08 01:42:59

标签: java spring firebase spring-boot firebase-authentication

我一直在尝试在使用Spring的服务器端集成一些Firebase功能。

显然,Spring可以决定多次启动public static void main(从现在开始,我称其为“ main”)方法。 (为什么?)

问题是Firebase需要我们的服务器进行身份验证才能使用某些Admin SDK功能(例如,验证idToken的签名)。我以为这通常会用在main方法中,但实际上它被调用了两次,这导致了FirebaseApp with name [DEFAULT] already exist.异常。

我想有两种解决方案,所以我会问两个问题:

  1. 如何防止Spring多次运行main? (为什么还要这么做?)
  2. 如何防止两次调用服务器身份验证? (也许一个简单的private static boolean属性就足够了,但是我觉得应该有一种更好的方法来解决这个问题。)

编辑:似乎“布尔”方法甚至不起作用。我猜想Spring的第二个调用是异步的。

编辑:

这里是main()代码(authenticateServer()方法在Spring启动之前运行了两次):

package hackqc18.Acclimate;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import hackqc18.Acclimate.authentication.VerifyToken;
import hackqc18.Acclimate.notifications.PushNotifServiceImpl;
import java.io.FileInputStream;
import java.util.ArrayList;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling

public class AcclimateApplication {

    public static void main(String[] args) {

        // Nécessaire!
        authenticateServer();

        SpringApplication.run(AcclimateApplication.class, args);
    }


    /**
     * Utilisé pour démontrer comment utiliser certaines fonctionnalités.
     */
    private static void demonstrationTemplate() {

    // [ Exemple de PUSH NOTIFICATION vers 2 appareils ]
        ArrayList<String> listOfDevices = new ArrayList<>();
        listOfDevices.add("...");
        listOfDevices.add("...");
        PushNotifServiceImpl.sendPushNotification(listOfDevices,"Test","Backend SPAMMMMMMM!");
    // [ Fin de l'exemple de notifs ]


    // [ Exemple de vérification d'un "idToken" et extraction du UID ]
        String idToken = "...";
        String uID = VerifyToken.verifyIdToken(idToken);
        System.out.println("Identified uID: " + uID);
    // [ Fin de l'exemple ]


    // TODO: CETTE MÉTHODE NE FONCTIONNE TOUJOURS PAS !!
    // [ Exemple d'envoie d'une notif à un appareil ]
        String registrationToken = "...";
        PushNotifServiceImpl.sendThroughGoogle(registrationToken);
    // [ Fin de l'envoie ]
    }

    /**
     * Admin SDK API (Firebase) - nécessaire
     * Pour authentifier le serveur d'Acclimate au serveur de Firebase.
     * Permet d'utiliser les fonctionnalités de l'Admin SDK.
     */
    private static void authenticateServer() {

        try {
            // [ Obtenir l'instance de Firebase App pour utiliser Admin SDK ]
            FileInputStream serviceAccount = new FileInputStream("abc.json");

            FirebaseOptions options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                    .setDatabaseUrl("https://bob.com/")
                    .build();

            FirebaseApp.initializeApp(options);
            // [ Fin de la validation du Admin SDK API ]
        } catch (Exception e) {
            e.printStackTrace();
        }

        // TODO: Juste là pour des fins de démonstration.
        demonstrationTemplate();
    }
}

编辑:添加更多代码。

这里是AppConfig.java

package hackqc18.Acclimate;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
@ComponentScan("hackqc18")
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**");
    }
}

这里是pom.xml

<?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>hackqc18</groupId>
    <artifactId>Acclimate</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>Acclimate</name>
    <description>Hackathon Québec 2018</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <geotools.version>18.1</geotools.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geojson</artifactId>
            <version>${geotools.version}</version>
        </dependency>
        <dependency>
            <groupId>org.geotools</groupId>
            <artifactId>gt-geometry</artifactId>
            <version>${geotools.version}</version>
        </dependency>

        <!-- <dependency> <groupId>com.bedatadriven</groupId> <artifactId>jackson-datatype-jts</artifactId> 
            <version>2.2</version> </dependency> -->
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-core</artifactId>
        </dependency>
<!-- Jeremi added Firebase Admin SDK -->
        <dependency>
            <groupId>com.google.firebase</groupId>
            <artifactId>firebase-admin</artifactId>
            <version>6.3.0</version>
        </dependency>
<!-- Firebase Admin SDK-->

<!--        <dependency> -->
<!--            <groupId>org.apache.derby</groupId> -->
<!--            <artifactId>derby</artifactId> -->
<!--            <scope>runtime</scope> -->
<!--        </dependency> -->
<!--        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency> -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency> 
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- >
            <plugin>
                <groupId>pl.project13.maven</groupId>
                <artifactId>git-commit-id-plugin</artifactId>
            </plugin>
            <-->
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>osgeo</id>
            <name>Open Source Geospatial Foundation Repository</name>
            <url>http://download.osgeo.org/webdav/geotools/</url>
        </repository>
        <repository>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <id>boundless</id>
            <name>Boundless Maven Repository</name>
            <url>http://repo.boundlessgeo.com/main</url>
        </repository>
    </repositories>

</project>

这里是nbactions.xml

<?xml version="1.0" encoding="UTF-8"?>
<actions>
    <action>
        <actionName>run</actionName>
        <packagings>
            <packaging>jar</packaging>
        </packagings>
        <goals>
            <goal>process-classes</goal>
            <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
        </goals>
        <properties>
            <exec.args>-classpath %classpath hackqc18.Acclimate.AcclimateApplication</exec.args>
            <exec.executable>java</exec.executable>
        </properties>
    </action>
</actions>

编辑:这是我在Spring实际启动之前收到的消息。我在main()中的方法在此消息之前被调用一次,在此消息之后被调用一次。然后,Spring实际上开始了。

The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-geojson\18.1\gt-geojson-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-main-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-api-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jdom-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/json-simple-1.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/commons-lang-2.6.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geojson/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-main\18.1\gt-main-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-api-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jdom-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-main/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-api\18.1\gt-api-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-api/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-referencing\18.1\gt-referencing-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-referencing/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-metadata\18.1\gt-metadata-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/jai_core-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-metadata/18.1/jts-core-1.14.0.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-opengis\18.1\gt-opengis-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-opengis/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-opengis/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-opengis/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\org\geotools\gt-geometry\18.1\gt-geometry-18.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jsr-275-1.0-beta-2.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-main-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-api-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jts-core-1.14.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jdom-1.1.3.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-referencing-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/core-0.26.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/commons-pool-1.5.4.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-metadata-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/gt-opengis-18.1.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jgridshift-1.0.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/GeographicLib-Java-1.44.jar,file:/C:/Users/PC/.m2/repository/org/geotools/gt-geometry/18.1/jai_core-1.1.3.jar
The Class-Path manifest attribute in C:\Users\PC\.m2\repository\io\grpc\grpc-netty-shaded\1.10.1\grpc-netty-shaded-1.10.1.jar referenced one or more files that do not exist: file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/grpc-core-1.10.1.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/grpc-context-1.10.1.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/gson-2.7.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/opencensus-contrib-grpc-metrics-0.11.0.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/opencensus-api-0.11.0.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/guava-19.0.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/error_prone_annotations-2.1.2.jar,file:/C:/Users/PC/.m2/repository/io/grpc/grpc-netty-shaded/1.10.1/jsr305-3.0.0.jar
12:51:34.090 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : []
12:51:34.125 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-starter-[\w-]+/, /spring-boot/target/classes/, /spring-boot-starter/target/classes/, /spring-boot-devtools/target/classes/, /spring-boot-actuator/target/classes/, /spring-boot-autoconfigure/target/classes/]
12:51:34.125 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/C:/Users/PC/Documents/GitHub/acclimateServer/target/classes/]
2018-08-09 12:51:36.273 DEBUG 10984 --- [  restartedMain] .c.l.ClasspathLoggingApplicationListener : Application started with classpath: [file:/C:/Users/PC/Documents/GitHub/acclimateServer/target/classes/]

1 个答案:

答案 0 :(得分:0)

发现devtools是造成这种奇怪行为的原因。我只是删除了pom.xml的这一部分来解决此问题:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
</dependency>