GraalVM无法与数据库连接配合使用。

3

我尝试使用Graalvm构建本地镜像,但每次在项目中使用数据库连接(例如H2 DB)通过mvn gluonfx:build构建时都会出现错误。

  • 没有数据库连接时,普通运行是可以成功的。
  • 成功构建本地镜像需要去掉任何数据库连接。

这里是pom文件的代码:

<groupId>com.example</groupId>
<artifactId>demo1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo1</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.release>11</maven.compiler.release>
    <javafx.version>17.0.0.1</javafx.version>
    <attach.version>4.0.12</attach.version>
    <gluonfx.plugin.version>1.0.15</gluonfx.plugin.version>
    <javafx.plugin.version>0.0.7</javafx.plugin.version>
    <main.class>com.example.demo1.main.Driver</main.class>
    <junit.version>5.7.1</junit.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-controls</artifactId>
        <version>${javafx.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-graphics</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-media</artifactId>
        <version>${javafx.version}</version>
    </dependency>
    <dependency>
        <groupId>org.openjfx</groupId>
        <artifactId>javafx-fxml</artifactId>
        <version>${javafx.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-controls</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.gluonhq</groupId>
        <artifactId>charm-glisten</artifactId>
        <version>6.0.6</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>display</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>lifecycle</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>statusbar</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>storage</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>util</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>org.bytedeco</groupId>
        <artifactId>javacpp</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.0.0</version>
    </dependency>
    <dependency>
        <groupId>net.jthink</groupId>
        <artifactId>jaudiotagger</artifactId>
        <version>3.0.1</version>
    </dependency>
    <dependency>
        <groupId>com.googlecode.soundlibs</groupId>
        <artifactId>jlayer</artifactId>
        <version>1.0.1.4</version>
    </dependency>
    <dependency>
        <groupId>com.googlecode.soundlibs</groupId>
        <artifactId>mp3spi</artifactId>
        <version>1.9.5-1</version>
        <exclusions>
            <exclusion>
                <groupId>com.googlecode.soundlibs</groupId>
                <artifactId>tritonus-share</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>com.googlecode.soundlibs</groupId>
        <artifactId>tritonus-share</artifactId>
        <version>0.3.7.4</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>2.1.214</version>
    </dependency>

</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
        </plugin>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>${javafx.plugin.version}</version>
            <configuration>
                <mainClass>${main.class}</mainClass>
            </configuration>
        </plugin>
        <plugin>
            <groupId>com.gluonhq</groupId>
            <artifactId>gluonfx-maven-plugin</artifactId>
            <version>${gluonfx.plugin.version}</version>
            <configuration>
                <target>${gluonfx.target}</target>
                <nativeImageArgs>
                    <nativeImageArg>--allow-incomplete-classpath</nativeImageArg>
                </nativeImageArgs>
                <attachList>
                    <list>display</list>
                    <list>lifecycle</list>
                    <list>statusbar</list>
                    <list>storage</list>
                </attachList>
                <mainClass>${main.class}</mainClass>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-maven-plugin</artifactId>
            <version>0.0.7</version>
            <executions>
                <execution>
                    <!-- Default configuration for running with: mvn clean javafx:run -->
                    <id>default-cli</id>
                    <configuration>
                        <mainClass>com.example.demo1/com.example.demo1.HelloApplication</mainClass>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<profiles>
    <profile>
        <id>ios</id>
        <properties>
            <gluonfx.target>ios</gluonfx.target>
        </properties>
    </profile>
    <profile>
        <id>android</id>
        <properties>
            <gluonfx.target>android</gluonfx.target>
        </properties>
    </profile>
</profiles>
<repositories>
    <repository>
        <id>gluon-releases</id>
        <url>https://nexus.gluonhq.com/nexus/content/repositories/releases/</url>
    </repository>
</repositories>

以下是主要类:

package com.example.demo1.main;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;

import java.sql.Connection;
import java.sql.DriverManager;

public class Driver extends Application {
@Override
public void start(Stage stage) throws Exception {
    Class.forName("org.h2.Driver");
    String str = "";
    Connection con= DriverManager.getConnection(
            "","","");
        str = str + con + "\n";
    con.close();
    Scene scene = new Scene(new Label(str),500,500);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}
}

以下是错误信息:

[INFO] Scanning for projects...
[WARNING] 
[WARNING] Some problems were encountered while building the effective model for com.example:demo1:jar:1.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.openjfx:javafx-maven-plugin @ line 159, column 21
[WARNING] 
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING] 
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING] 
[INFO] 
[INFO] -------------------------< com.example:demo1 >--------------------------
[INFO] Building demo1 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- gluonfx-maven-plugin:1.0.15:build (default-cli) @ demo1 ---
[INFO] Scanning for projects...
[WARNING] 
[WARNING] Some problems were encountered while building the effective model for com.example:demo1:jar:1.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.openjfx:javafx-maven-plugin @ line 159, column 21
[WARNING] 
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING] 
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING] 
[INFO] 
[INFO] -------------------------< com.example:demo1 >--------------------------
[INFO] Building demo1 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] >>> gluonfx-maven-plugin:1.0.15:compile (default-cli) > process-classes @ demo1 >>>
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo1 ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ demo1 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 4 source files to /Users/yousefhamarsheh/Desktop/demo1/target/classes
[INFO] 
[INFO] <<< gluonfx-maven-plugin:1.0.15:compile (default-cli) < process-classes @ demo1 <<<
[INFO] 
[INFO] 
[INFO] --- gluonfx-maven-plugin:1.0.15:compile (default-cli) @ demo1 ---
Aug 30, 2022 12:20:55 PM com.gluonhq.substrate.util.Logger logInfo
INFO: Substrate is tested with the Gluon's GraalVM build which you can find at https://github.com/gluonhq/graal/releases.
While you can still use other GraalVM builds, there is no guarantee that these will work properly with Substrate
[Tue Aug 30 12:20:55 EEST 2022][INFO] ==================== COMPILE TASK ====================
             _______  ___      __   __  _______  __    _
            |       ||   |    |  | |  ||       ||  |  | |
            |    ___||   |    |  | |  ||   _   ||   |_| |
            |   | __ |   |    |  |_|  ||  | |  ||       |
            |   ||  ||   |___ |       ||  |_|  ||  _    |
            |   |_| ||       ||       ||       || | |   |
            |_______||_______||_______||_______||_|  |__|

    Access to the latest docs, tips and tricks and more info on
    how to get support? Register your usage of Gluon Substrate now at

    https://gluonhq.com/activate



[Tue Aug 30 12:20:56 EEST 2022][INFO] We will now compile your code for aarch64-apple-darwin. This may take some time.
[Tue Aug 30 12:20:57 EEST 2022][INFO] [SUB] Warning: Ignoring server-mode native-image argument --no-server.
[Tue Aug 30 12:20:57 EEST 2022][INFO] [SUB] Warning: Using a deprecated option --allow-incomplete-classpath from command line. Allowing an incomplete classpath is now the default. Use --link-at-build-time to report linking errors at image build time for a class or package.
[Tue Aug 30 12:21:01 EEST 2022][INFO] [SUB] ========================================================================================================================
[Tue Aug 30 12:21:01 EEST 2022][INFO] [SUB] GraalVM Native Image: Generating 'com.example.demo1.main.driver' (shared library)...
[Tue Aug 30 12:21:01 EEST 2022][INFO] [SUB] ========================================================================================================================
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB] [1/7] Initializing...                                                                                    (6.6s @ 0.21GB)
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB]  Version info: 'GraalVM 22.2.0 Java 17 CE'
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB]  Java version info: '17.0.4+8-jvmci-22.2-b06'
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB]  C compiler: cc (apple, arm64, 13.0.0)
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB]  Garbage collector: Serial GC
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB]  1 user-specific feature(s)
[Tue Aug 30 12:21:05 EEST 2022][INFO] [SUB]  - org.graalvm.home.HomeFinderFeature: Finds GraalVM paths and its version number
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB] [2/7] Performing analysis...  [*********]                                                               (63.3s @ 2.08GB)
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB]   13,955 (91.53%) of 15,247 classes reachable
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB]   27,104 (69.81%) of 38,823 fields reachable
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB]   72,186 (66.16%) of 109,109 methods reachable
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB]      675 classes,   185 fields, and 2,214 methods registered for reflection
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB]      118 classes,   111 fields, and   193 methods registered for JNI access
[Tue Aug 30 12:22:08 EEST 2022][INFO] [SUB]        5 native libraries: -framework CoreServices, -framework Foundation, dl, pthread, z
[Tue Aug 30 12:22:19 EEST 2022][INFO] [SUB] [3/7] Building universe...                                                                              (10.9s @ 1.39GB)
[Tue Aug 30 12:22:29 EEST 2022][INFO] [SUB] [4/7] Parsing methods...      [***]                                                                      (9.2s @ 2.57GB)
[Tue Aug 30 12:22:37 EEST 2022][INFO] [SUB] [5/7] Inlining methods...     [****]                                                                     (7.1s @ 1.74GB)
[Tue Aug 30 12:23:41 EEST 2022][INFO] [SUB] [6/7] Compiling methods...    [********]                                                                (64.5s @ 3.11GB)
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB] 
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB] ------------------------------------------------------------------------------------------------------------------------
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB]                        24.7s (13.5% of total time) in 57 GCs | Peak RSS: 1.92GB | CPU load: 4.32
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB] ------------------------------------------------------------------------------------------------------------------------
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB] Produced artifacts:
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB]  /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/demo1/com.example.demo1.main.driver.build_artifacts.txt (txt)
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB]  /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/demo1/com.example.demo1.main.driver.h (header)
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB]  /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/demo1/com.example.demo1.main.driver_dynamic.h (header)
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB]  /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/demo1/graal_isolate.h (header)
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB]  /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/demo1/graal_isolate_dynamic.h (header)
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB] ========================================================================================================================
[Tue Aug 30 12:24:01 EEST 2022][INFO] [SUB] Finished generating 'com.example.demo1.main.driver' in 3m 2s.
[INFO] 
[INFO] --- gluonfx-maven-plugin:1.0.15:link (default-cli) @ demo1 ---
[Tue Aug 30 12:24:01 EEST 2022][INFO] Substrate is tested with the Gluon's GraalVM build which you can find at https://github.com/gluonhq/graal/releases.
While you can still use other GraalVM builds, there is no guarantee that these will work properly with Substrate
[Tue Aug 30 12:24:01 EEST 2022][INFO] ==================== LINK TASK ====================
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB] Undefined symbols for architecture arm64:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]   "_JNI_OnLoad_jaas", referenced from:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]       ___svm_vm_target_staticlibraries in com.example.demo1.main.driver.o
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]   "_Java_com_sun_management_internal_OperatingSystemImpl_getTotalMemorySize0", referenced from:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]       ___svm_vm_target_libraries in com.example.demo1.main.driver.o
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]   "_Java_com_sun_management_internal_OperatingSystemImpl_initialize0", referenced from:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]       ___svm_vm_target_libc in com.example.demo1.main.driver.o
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]   "_Java_com_sun_security_auth_module_UnixSystem_getUnixInfo", referenced from:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]       ___svm_vm_target_libc in com.example.demo1.main.driver.o
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB] ld: symbol(s) not found for architecture arm64
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB] clang: error: linker command failed with exit code 1 (use -v to see invocation)
[Tue Aug 30 12:24:03 EEST 2022][SEVERE] Process link failed with result: 1
Check the log files under /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/log
And please check https://docs.gluonhq.com/ for more information.
[Tue Aug 30 12:24:03 EEST 2022][INFO] Logging process [link] to file: /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/log/process-link-1661851443149.log
[Tue Aug 30 12:24:03 EEST 2022][SEVERE] Linking failed.
Check the log files under /Users/yousefhamarsheh/Desktop/demo1/target/gluonfx/aarch64-darwin/gvm/log
And please check https://docs.gluonhq.com/ for more information.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:09 min
[INFO] Finished at: 2022-08-30T12:24:03+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.gluonhq:gluonfx-maven-plugin:1.0.15:link (default-cli) on project demo1: Linking failed -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  03:10 min
[INFO] Finished at: 2022-08-30T12:24:03+03:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.gluonhq:gluonfx-maven-plugin:1.0.15:build (default-cli) on project demo1: Error, gluonfx:build failed -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

1个回答

4

您遇到了链接错误:

[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB] Undefined symbols for architecture arm64:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]   "_JNI_OnLoad_jaas", referenced from:
[Tue Aug 30 12:24:03 EEST 2022][INFO] [SUB]       ___svm_vm_target_staticlibraries in com.example.demo1.main.driver.o

如果你这么做:

$ nm target/gluonfx/aarch64-darwin/gvm/tmp/SVM-166XXXXX/com.example.demo1.main.driver.o | grep jaas
                 U _JNI_OnLoad_jaas

这意味着您的本地映像对象中存在未解决的符号(由于 gluonfx:compile导致),应在链接时进行修复(使用 gluonfx:link)。

您可以在日志中看到链接命令,它应该类似于:

gcc /HelloFX/target/gluonfx/aarch64-darwin/gvm/HelloFX/AppDelegate.o /HelloFX/target/gluonfx/aarch64-darwin/gvm/HelloFX/launcher.o \
/HelloFX/target/gluonfx/aarch64-darwin/gvm/tmp/SVM-1661853087924/hellofx.hellofx.o \
-ljava -lnio -lzip -lnet -lprefs -lj2pkcs11 -lfdlibm -lextnet -ljvm -llibchelper -ldarwin -lpthread -lz -ldl -lstdc++ \
-mmacosx-version-min=10.12 -lobjc -Wl,-framework,Foundation ... \
-Wl,-force_load,~/.gluon/substrate/javafxStaticSdk/19-ea+8/darwin-aarch64/sdk/lib/libglass.a ... \
-o /HelloFX/target/gluonfx/aarch64-darwin/HelloFX -L~/.gluon/substrate/javafxStaticSdk/19-ea+8/darwin-aarch64/sdk/lib \
-L/~/.gluon/substrate/graalvm/graalvm-svm-java17-darwin-m1-gluon-22.1.0.1-Final/Contents/Home/lib/svm/clibraries/darwin-aarch64 \ 
-L/~/.gluon/substrate/graalvm/graalvm-svm-java17-darwin-m1-gluon-22.1.0.1-Final/Contents/Home/lib/static/darwin-aarch64

请注意已添加的库:libjava.alibnio.alibnet.a等。

这些库来自于 ~/.gluon/substrate/graalvm/graalvm-svm-java17-darwin-m1-gluon-22.1.0.1-Final/Contents/Home/lib/static/darwin-aarch64

然而,libjaas.a 库没有被链接,这就解释了上面的错误。

好消息是该路径中带有其他库,其中包括缺失的库,因此您可以使用linkerArgs轻松将其包含在链接命令中:

           <plugin>
                <groupId>com.gluonhq</groupId>
                <artifactId>gluonfx-maven-plugin</artifactId>
                <version>${gluonfx.maven.plugin.version}</version>
                <configuration>
                     <target>${gluonfx.target}</target>
                     <mainClass>${main.class}</mainClass>
                     <linkerArgs>
                         <arg>-ljaas</arg>
                     </linkerArgs>
                </configuration>
            </plugin>

现在再次运行mvn gluonfx:link,链接错误应该已经消失。
一些其他提示:
  • 使用推荐的GraalVM 22.1.0.1-Final Gluon版本(请参见文档
  • 在构建本地映像之前,请先运行mvn gluonfx:runagent,以发现项目中所有反射的用途。
  • 不要使用--allow-incomplete-classpath,最好事先修复错误。
  • 基于您的依赖项,GluonFX插件对媒体的支持非常有限(请参见文档)。

我非常感谢您的解释,它确实帮助我更好地理解了Graalvm,但问题仍未解决。当我运行链接命令时,这些内容会出现在Undefined symbols for architecture arm64中:_Java_com_sun_management_internal_OperatingSystemImpl_getTotalMemorySize0被引用,来自com.example.demo1.main.driver.o中的___svm_vm_java_version_Java_com_sun_management_internal_OperatingSystemImpl_initialize0被引用,来自com.example.demo1.main.driver.o中的___svm_vm_java_versionld:找不到架构arm64的符号 - Yousef Hamarsheh
另一个问题是,是否存在特定的依赖关系会影响链接过程? - Yousef Hamarsheh
我只使用了com.h2database:h2依赖项,这是您演示代码所需的依赖项。那些符号可能确实来自其他依赖项。 - José Pereda
版本2.1.214? - Yousef Hamarsheh
是的,您发布的那个。 - José Pereda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接