0

現在、GraalVM ネイティブ イメージ ツールを試しています。目標は、postgresql でスプリング ブート Web アプリケーションを実行することです。

私のプロジェクトは mvn clean パッケージでコンパイルされ、.JAR は docker-postgresql で魅力的に動作しますが、これからネイティブ イメージを構築することはできません。

Josh Long の Spring のヒントからこのきちんとしたコンパイル スクリプトを見つけました。これは、以前のプロジェクトの構成に大いに役立ちました。これまでのところ、StringIndexOutOfBoundsException をスローするだけなので、ネイティブ イメージがビルドされない理由がわかりません。h2とjpaを使用した別のプロジェクトがあり、まったく同じパラメーターでそれを行います。

構成またはエクスペリエンスと ofc ソリューションを変更する場所に関するいくつかの提案を期待しています。

現在、GraalVM バージョン 20.1.0 (Java バージョン 1.8.0_252) を JDK として使用しています。

以下は、スタックトレースとサンプル プロジェクトです。また、./compile.sh のターミナル出力をhttps://file.io/HXudRpH80dDzにアップロードしました。

Fatal error:java.lang.StringIndexOutOfBoundsException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598)
    at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1005)
    at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:463)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:359)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:518)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:117)
Caused by: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1967)
    at org.springframework.graalvm.type.TypeSystem.resolve(TypeSystem.java:208)
    at org.springframework.graalvm.type.Method.getReturnType(Method.java:199)
    at org.springframework.graalvm.type.Type.collectAtMappingMarkedReturnTypes(Type.java:1655)
    at org.springframework.graalvm.support.ResourcesHandler.processResponseBodyComponent(ResourcesHandler.java:428)
    at org.springframework.graalvm.support.ResourcesHandler.processSpringComponents(ResourcesHandler.java:310)
    at org.springframework.graalvm.support.ResourcesHandler.processExistingOrSynthesizedSpringComponentsFiles(ResourcesHandler.java:177)
    at org.springframework.graalvm.support.ResourcesHandler.register(ResourcesHandler.java:124)
    at org.springframework.graalvm.support.SpringFeature.beforeAnalysis(SpringFeature.java:78)
    at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$7(NativeImageGenerator.java:679)
    at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:70)
    at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:679)
    at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:538)
    at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:451)
    at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
    at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
    at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
    at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
    at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Error: Image build request failed with exit status 1
com.oracle.svm.driver.NativeImage$NativeImageError: Image build request failed with exit status 1
    at com.oracle.svm.driver.NativeImage.showError(NativeImage.java:1541)
    at com.oracle.svm.driver.NativeImage.build(NativeImage.java:1299)
    at com.oracle.svm.driver.NativeImage.performBuild(NativeImage.java:1260)
    at com.oracle.svm.driver.NativeImage.main(NativeImage.java:1219)

real    0m36,107s
user    1m0,314s
sys 0m2,100s

コンパイル.sh

#!/usr/bin/env bash

ARTIFACT=${1}
MAINCLASS=${2}
VERSION=${3}

JAR="${ARTIFACT}-${VERSION}.jar"

rm -rf target
mkdir -p target/native-image
mvn package  
rm -f $ARTIFACT
cd target/native-image
jar -xvf ../$JAR  
cp -R META-INF BOOT-INF/classes

LIBPATH=`find BOOT-INF/lib | tr '\n' ':'`
CP=BOOT-INF/classes:$LIBPATH
GRAALVM_VERSION=`native-image --version`

time native-image \
  --verbose \
  -H:EnableURLProtocols=http \
  -H:+RemoveSaturatedTypeFlows \
  -H:Name=$ARTIFACT \
  -H:+TraceClassInitialization \
  --initialize-at-build-time=org.springframework.util.unit.DataSize \
  -H:+ReportExceptionStackTraces  \
  -Dspring.native.verbose=true \
  -Dspring.native.remove-jmx-support=true \
  -Dspring.native.remove-spel-support=true \
  -Dspring.native.remove-yaml-support=true \
  -cp $CP $MAINCLASS  \
  --no-fallback\
  --allow-incomplete-classpath\
  -Dspring.native.remove-xml-support=true 

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>postgres</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for postgresql native-image</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--  -->
        <dependency>
            <groupId>org.springframework.experimental</groupId>
            <artifactId>spring-graalvm-native</artifactId>
            <version>0.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-indexer</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.3.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</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.hibernate.orm.tooling</groupId>
                <artifactId>hibernate-enhance-maven-plugin</artifactId>
                <version>${hibernate.version}</version>
                <executions>
                    <execution>
                        <configuration>
                            <failOnError>true</failOnError>
                            <enableLazyInitialization>true</enableLazyInitialization>
                            <enableDirtyTracking>true</enableDirtyTracking>
                            <enableExtendedEnhancement>false</enableExtendedEnhancement>
                        </configuration>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

アプリケーションのプロパティ

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.show-sql=true
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=admin


spring.datasource.initialization-mode=always
spring.datasource.schema=classpath:/schema.sql
spring.datasource.continue-on-error=true

PostgresApplication.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration;

@SpringBootApplication(
        exclude = SpringDataWebAutoConfiguration.class,
        proxyBeanMethods = false
)
public class PostgresApplication {

    public static void main(String[] args) {
        SpringApplication.run(PostgresApplication.class, args);
    }

}

従業員.java

public class Employee {

String employeeId;
String employeeName;
String employeeEmail;
String employeeAddress;


public String getEmployeeEmail() {
    return employeeEmail;
}
public void setEmployeeEmail(String employeeEmail) {
    this.employeeEmail = employeeEmail;
}
public String getEmployeeId() {
    return employeeId;
}
public void setEmployeeId(String employeeId) {
    this.employeeId = employeeId;
}
public String getEmployeeName() {
    return employeeName;
}
public void setEmployeeName(String employeeName) {
    this.employeeName = employeeName;
}
public String getEmployeeAddress() {
    return employeeAddress;
}
public void setEmployeeAddress(String employeeAddress) {
    this.employeeAddress = employeeAddress;
}}

EmployeeRowMapper.java

import java.sql.ResultSet;
import java.sql.SQLException;

import com.example.postgres.entity.Employee;
import org.springframework.jdbc.core.RowMapper;

public class EmployeeRowMapper implements RowMapper<Employee> {

    @Override
    public Employee mapRow(ResultSet rs, int arg1) throws SQLException {
        Employee emp = new Employee();
        emp.setEmployeeId(rs.getString("employeeId"));
        emp.setEmployeeName(rs.getString("employeeName"));
        emp.setEmployeeEmail(rs.getString("employeeEmail"));
        emp.setEmployeeAddress(rs.getString("employeeAddress"));

        return emp;
    }
}

EmployeeDao.java

import com.example.postgres.entity.Employee;

import java.util.List;

public interface EmployeeDao {

    List<Employee> findAll();

    void insertEmployee(Employee emp);

    void updateEmployee(Employee emp);

    void executeUpdateEmployee(Employee emp);

    public void deleteEmployee(Employee emp);
}

EmployeeDaoImpl.java

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.postgres.entity.Employee;
import com.example.postgres.mapper.EmployeeRowMapper;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDaoImpl implements EmployeeDao{
    
    public EmployeeDaoImpl(NamedParameterJdbcTemplate template) {  
        this.template = template;  
}  
    NamedParameterJdbcTemplate template;  

    @Override
    public List<Employee> findAll() {
        return template.query("select * from employee", new EmployeeRowMapper());
    }
    @Override
    public void insertEmployee(Employee emp) {
         final String sql = "insert into employee(employeeId, employeeName , employeeAddress,employeeEmail) values(:employeeId,:employeeName,:employeeEmail,:employeeAddress)";
         
            KeyHolder holder = new GeneratedKeyHolder();
            SqlParameterSource param = new MapSqlParameterSource()
                    .addValue("employeeId", emp.getEmployeeId())
                    .addValue("employeeName", emp.getEmployeeName())
                    .addValue("employeeEmail", emp.getEmployeeEmail())
                    .addValue("employeeAddress", emp.getEmployeeAddress());
            template.update(sql,param, holder);
     
    }
    
    @Override
    public void updateEmployee(Employee emp) {
         final String sql = "update employee set employeeName=:employeeName, employeeAddress=:employeeAddress, employeeEmail=:employeeEmail where employeeId=:employeeId";
         
            KeyHolder holder = new GeneratedKeyHolder();
            SqlParameterSource param = new MapSqlParameterSource()
                    .addValue("employeeId", emp.getEmployeeId())
                    .addValue("employeeName", emp.getEmployeeName())
                    .addValue("employeeEmail", emp.getEmployeeEmail())
                    .addValue("employeeAddress", emp.getEmployeeAddress());
            template.update(sql,param, holder);
     
    }
    
    @Override
    public void executeUpdateEmployee(Employee emp) {
         final String sql = "update employee set employeeName=:employeeName, employeeAddress=:employeeAddress, employeeEmail=:employeeEmail where employeeId=:employeeId";
             

         Map<String,Object> map=new HashMap<String,Object>();  
         map.put("employeeId", emp.getEmployeeId());
         map.put("employeeName", emp.getEmployeeName());
         map.put("employeeEmail", emp.getEmployeeEmail());
         map.put("employeeAddress", emp.getEmployeeAddress());
    
         template.execute(sql,map,new PreparedStatementCallback<Object>() {  
                @Override  
                public Object doInPreparedStatement(PreparedStatement ps)  
                        throws SQLException, DataAccessException {  
                    return ps.executeUpdate();  
                }  
            });  

     
    }
    
    @Override
    public void deleteEmployee(Employee emp) {
         final String sql = "delete from employee where employeeId=:employeeId";
             

         Map<String,Object> map=new HashMap<String,Object>();  
         map.put("employeeId", emp.getEmployeeId());
    
         template.execute(sql,map,new PreparedStatementCallback<Object>() {  
                @Override  
                public Object doInPreparedStatement(PreparedStatement ps)  
                        throws SQLException, DataAccessException {  
                    return ps.executeUpdate();  
                }  
            });  
    }
}

EmployeeService.java

import java.util.List;

import com.example.postgres.entity.Employee;

public interface EmployeeService {
    List<Employee> findAll();

    void insertEmployee(Employee emp);

    void updateEmployee(Employee emp);

    void executeUpdateEmployee(Employee emp);

    void deleteEmployee(Employee emp);
    
}

EmployeeServiceImpl.java

import javax.annotation.Resource;
import java.util.List;

import com.example.postgres.dao.EmployeeDao;
import com.example.postgres.entity.Employee;
import org.springframework.stereotype.Component;

@Component
public class EmployeeServiceImpl implements EmployeeService{
    @Resource
    EmployeeDao employeeDao;
    @Override
    public List<Employee> findAll() {
        return employeeDao.findAll();
    }
    @Override
    public void insertEmployee(Employee emp) {
        employeeDao.insertEmployee(emp);
        
    }
    @Override
    public void updateEmployee(Employee emp) {
        employeeDao.updateEmployee(emp);
        
    }
    @Override
    public void executeUpdateEmployee(Employee emp) {
        employeeDao.executeUpdateEmployee(emp);
        
    }

    @Override
    public void deleteEmployee(Employee emp) {
        employeeDao.deleteEmployee(emp);
        
    }
}

ApplicationController.java

import java.util.List;

import javax.annotation.Resource;

import com.example.postgres.entity.Employee;
import com.example.postgres.service.EmployeeService;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/postgresApp")
public class ApplicationController {

    @Resource
    EmployeeService employeeService;
    
    @GetMapping(value = "/employeeList")
    public List<Employee> getEmployees() {
        return employeeService.findAll();
    
    }
    
    @PostMapping(value = "/createEmp")
    public void createEmployee(@RequestBody Employee emp) {
         employeeService.insertEmployee(emp);
    
    }
    @PutMapping(value = "/updateEmp")
    public void updateEmployee(@RequestBody Employee emp) {
         employeeService.updateEmployee(emp);
    
    }
    @PutMapping(value = "/executeUpdateEmp")
    public void executeUpdateEmployee(@RequestBody Employee emp) {
         employeeService.executeUpdateEmployee(emp);
    
    }
    
    @DeleteMapping(value = "/deleteEmpById")
    public void deleteEmployee(@RequestBody Employee emp) {
         employeeService.deleteEmployee(emp);
    
    }
    
}
4

0 に答える 0