Использование внедрения Vertex AI в приложении Spring BootJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Использование внедрения Vertex AI в приложении Spring Boot

Сообщение Anonymous »

Я собираюсь использовать Google VertexAI Text Embeddings для встраивания текста перед сохранением в pgvectordb.
Pom.xml

Код: Выделить всё

21

2.0.0-M2




org.springframework.ai
spring-ai-starter-model-vertex-ai-embedding



org.springframework.ai
spring-ai-starter-vector-store-pgvector






org.springframework.ai
spring-ai-bom
${spring-ai.version}
pom
import



application.properties

Код: Выделить всё

# --- 1. GLOBAL CONFIG (Required for the Connection Bean) ---
spring.ai.vertex.ai.embedding.project-id=MYPROJECTID(from GCP console)
spring.ai.vertex.ai.embedding.location=us-central1

# --- 2. EMBEDDING SPECIFICS ---
spring.ai.vertex.ai.embedding.text.options.model=text-embedding-005
spring.ai.vertex.ai.embedding.text.options.dimensions=768

# --- 3. DATABASE (Docker) ---
spring.datasource.url=jdbc:postgresql://localhost:5432/rag_app_db
spring.datasource.username=postgres
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver

# JPA / Hibernate
spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

# --- 4. Spring AI Vector Store (PGVector) ---
spring.ai.vectorstore.pgvector.index-type=HNSW
spring.ai.vectorstore.pgvector.distance-type=COSINE_DISTANCE
spring.ai.vectorstore.pgvector.dimensions=768
spring.ai.vectorstore.pgvector.initialize-schema=true
Я проверил подключение к GCP с помощью этой программы в Spring Boot (помощь в этом вопросе по аутентификации Spring-boot-google-vertex-ai):

Код: Выделить всё

import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Collections;

@Component
public class CredentialCheck implements CommandLineRunner {

@Override
public void run(String... args) {
System.out.println("----------------------------------------");
System.out.println("🔍 TESTING GOOGLE CLOUD CREDENTIALS...");
System.out.println("----------------------------------------");

try {
// 1. Load credentials exactly how Spring AI does it
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();

// 2. ADD SCOPE
if (credentials.createScopedRequired()) {
credentials = credentials.createScoped("https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/cloud-platform.read-only");
}

// 3.  Now try to refresh
credentials.refreshIfExpired();

System.out.println("✅ SUCCESS! Credentials Valid & Active.");

if (credentials instanceof ServiceAccountCredentials) {
System.out.println("🆔 Identity: " + ((ServiceAccountCredentials) credentials).getClientEmail());
System.out.println("📂 Source: JSON Key File (Docker Ready)");
}

} catch (Exception e) {
System.err.println("❌ FAILED: " + e.getMessage());
}

System.out.println("----------------------------------------");
}
}
и вывод был УСПЕШНЫМ.

Код: Выделить всё

----------------------------------------
? TESTING GOOGLE CLOUD CREDENTIALS...
----------------------------------------
? SUCCESS! Credentials Valid & Active.
? Identity: MYSERVICEACCOUT@MYPROJECTID.iam.gserviceaccount.com
? Source: JSON Key File (Docker Ready)
----------------------------------------
Вышеупомянутые учетные данные, к которым он получил доступ через файл json, который я скачал с консоли GCP, и указал переменную среды Windows на ее местоположение:
Изображение

Чтобы запустить этот тест, я прокомментировал две зависимости и прокомментировал строки сохранения вложений в базе данных pgvector из этого кода уровня службы:

Код: Выделить всё

@Service
public class HeelpDataService {

private final HeelpDataRepository repository;
private final VectorStore vectorStore; //COMMENTED this and all the methods, constructors etc.  while testing GCP connectivity

@Autowired
public HeelpDataService(HeelpDataRepository repository, VectorStore vectorStore) {
this.repository = repository;
this.vectorStore = vectorStore;
}

public HeelpData createData(HeelpData data) {
HeelpData savedData = repository.save(data);
// syncToVectorStore(savedData);
return savedData;
}

public List getAllData() {
return repository.findAll();
}

public Optional getDataById(Long id) {
return repository.findById(id);
}

public HeelpData updateData(Long id, HeelpData dataDetails) {
return repository.findById(id).map(existingData -> {
existingData.setUrl(dataDetails.getUrl());
existingData.setText_content(dataDetails.getText_content());
HeelpData savedData = repository.save(existingData);

// Sync to vector store: simpler approach is to delete old and add new
// Assuming source_id is unique enough for us to use for deletion
deleteFromVectorStore(id);
syncToVectorStore(savedData);

return savedData;
}).orElse(null);
}

public void deleteData(Long id) {
repository.deleteById(id);
deleteFromVectorStore(id);
}

private void syncToVectorStore(HeelpData data) {
if (data.getText_content() != null && !data.getText_content().isEmpty()) {
// Use the HeelpData ID as the Document ID for easy retrieval/deletion
Document document = new Document(data.getId().toString(),
data.getText_content(),
Map.of("source_id", data.getId(), "url", data.getUrl()));
vectorStore.add(List.of(document));
}
}

private void deleteFromVectorStore(Long id) {
// Delete using the ID we assigned (HeelpData ID ->  String)
vectorStore.delete(List.of(id.toString()));
}
}
Но после успешного тестирования GCP, когда я раскомментирую и пытаюсь сохранить в pgvector, я получаю журнал ошибок:

Код: Выделить всё

2026-01-31T09:31:32.772-05:00 ERROR 24932 --- [app-name] [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.IllegalStateException: Error processing condition on org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration.retryTemplate
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:99) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:183) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:430) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:290) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:791) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:609) ~[spring-context-6.2.11.jar:6.2.11]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.6.jar:3.5.6]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.6.jar:3.5.6]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.6.jar:3.5.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.6.jar:3.5.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.6.jar:3.5.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.6.jar:3.5.6]
at edu.unc.cs.heelp_ai.HeelpAiApplication.main(HeelpAiApplication.java:17) ~[classes/:na]
Caused by: java.lang.IllegalStateException: @ConditionalOnMissingBean did not specify a bean using type, name or annotation and the attempt to deduce the bean's type failed
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.validate(OnBeanCondition.java:630) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.(OnBeanCondition.java:577) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:142) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
...  17 common frames omitted
Caused by: org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanTypeDeductionException: Failed to deduce bean type for org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration.retryTemplate
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.deducedBeanTypeForBeanMethod(OnBeanCondition.java:659) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.deducedBeanType(OnBeanCondition.java:649) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.(OnBeanCondition.java:570) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
... 19 common frames omitted
Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.ai.retry.autoconfigure.SpringAiRetryAutoConfiguration] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@105be200]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:483) ~[spring-core-6.2.11.jar:6.2.11]
at org.springframework.util.ReflectionUtils.findMethod(ReflectionUtils.java:238) ~[spring-core-6.2.11.jar:6.2.11]
at org.springframework.util.ReflectionUtils.findMethod(ReflectionUtils.java:218) ~[spring-core-6.2.11.jar:6.2.11]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.findBeanMethod(OnBeanCondition.java:688) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.getMethodReturnType(OnBeanCondition.java:683) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.getReturnType(OnBeanCondition.java:667) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.deducedBeanTypeForBeanMethod(OnBeanCondition.java:656) ~[spring-boot-autoconfigure-3.5.6.jar:3.5.6]
... 21 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/core/retry/RetryListener
at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3010) ~[na:na]
at java.base/java.lang.Class.getDeclaredMethods(Class.java:2329) ~[na:na]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:465) ~[spring-core-6.2.11.jar:6.2.11]
... 27 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.core.retry.RetryListener
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580) ~[na:na]
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:490) ~[na:na]
...  31 common frames omitted

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
с debug=true в application.properties журнал ошибок огромен (поэтому я удалил много положительных и отрицательных совпадений:

Код: Выделить всё

============================
CONDITIONS EVALUATION REPORT
============================

Positive matches:
-----------------

AopAutoConfiguration matched:
- @ConditionalOnBooleanProperty (spring.aop.auto=true) matched (OnPropertyCondition)

AopAutoConfiguration.AspectJAutoProxyingConfiguration matched:
- @ConditionalOnClass found required class 'org.aspectj.weaver.Advice' (OnClassCondition)

AopAutoConfiguration.AspectJAutoProxyingConfiguration.CglibAutoProxyConfiguration matched:
- @ConditionalOnBooleanProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)

AuditAutoConfiguration matched:
- @ConditionalOnBooleanProperty (management.auditevents.enabled=true) matched (OnPropertyCondition)

ServletEndpointManagementContextConfiguration.WebMvcServletEndpointManagementContextConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)

ServletManagementContextAutoConfiguration matched:
- @ConditionalOnClass found required class 'jakarta.servlet.Servlet' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)

ServletWebServerFactoryAutoConfiguration matched:
- @ConditionalOnClass found required class 'jakarta.servlet.ServletRequest' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)

ServletWebServerFactoryAutoConfiguration#tomcatServletWebServerFactoryCustomizer matched:
- @ConditionalOnClass found required class 'org.apache.catalina.startup.Tomcat' (OnClassCondition)

ServletWebServerFactoryConfiguration.EmbeddedTomcat matched:
- @ConditionalOnClass found required classes 'jakarta.servlet.Servlet', 'org.apache.catalina.startup.Tomcat', 'org.apache.coyote.UpgradeProtocol' (OnClassCondition)
- @ConditionalOnMissingBean (types: org.springframework.boot.web.servlet.server.ServletWebServerFactory; SearchStrategy: current) did not find any beans (OnBeanCondition)

SimpleCacheConfiguration matched:
- Cache org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration automatic cache type (CacheCondition)

SimpleMetricsExportAutoConfiguration matched:
- @ConditionalOnEnabledMetricsExport management.defaults.metrics.export.enabled is considered true (OnMetricsExportEnabledCondition)
- @ConditionalOnBean (types: io.micrometer.core.instrument.Clock; SearchStrategy: all) found bean 'micrometerClock'; @ConditionalOnMissingBean (types: io.micrometer.core.instrument.MeterRegistry; SearchStrategy: all) did not find any beans (OnBeanCondition)

SimpleMetricsExportAutoConfiguration#simpleConfig matched:
- @ConditionalOnMissingBean (types: io.micrometer.core.instrument.simple.SimpleConfig;  SearchStrategy:  all) did not find any beans (OnBeanCondition)

SpringAiRetryAutoConfiguration matched:
- @ConditionalOnClass found required class 'org.springframework.ai.retry.RetryUtils' (OnClassCondition)

SpringDataWebAutoConfiguration matched:
- @ConditionalOnClass found required classes 'org.springframework.data.web.PageableHandlerMethodArgumentResolver', 'org.springframework.web.servlet.config.annotation.WebMvcConfigurer' (OnClassCondition)
- found 'session' scope (OnWebApplicationCondition)

XADataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource', 'jakarta.transaction.TransactionManager', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType' (OnClassCondition)

Negative matches:
-----------------

ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'jakarta.jms.ConnectionFactory' (OnClassCondition)

AopAutoConfiguration.AspectJAutoProxyingConfiguration.JdkDynamicAutoProxyConfiguration:
Did not match:
- @ConditionalOnBooleanProperty (spring.aop.proxy-target-class=false) did not find property 'spring.aop.proxy-target-class' (OnPropertyCondition)

AopAutoConfiguration.ClassProxyingConfiguration:
Did not match:
- @ConditionalOnMissingClass found unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)

AppOpticsMetricsExportAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'io.micrometer.appoptics.AppOpticsMeterRegistry' (OnClassCondition)

ArtemisAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'jakarta.jms.ConnectionFactory' (OnClassCondition)

AtlasMetricsExportAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'io.micrometer.atlas.AtlasMeterRegistry' (OnClassCondition)

AuditEventsEndpointAutoConfiguration:
Did not match:
- @ConditionalOnAvailableEndpoint not exposed (OnAvailableEndpointCondition)

AvailabilityProbesAutoConfiguration:
Did not match:
- Probes availability not running on a supported cloud platform (AvailabilityProbesAutoConfiguration.ProbesCondition)

BatchAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)

BatchObservationAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.batch.core.configuration.annotation.BatchObservabilityBeanPostProcessor' (OnClassCondition)

BeansEndpointAutoConfiguration:
Did not match:
- @ConditionalOnAvailableEndpoint not exposed (OnAvailableEndpointCondition)

BraveAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'brave.Tracer' (OnClassCondition)

Cache2kCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.cache2k.Cache2kBuilder' (OnClassCondition)

CacheMeterBinderProvidersConfiguration.Cache2kCacheMeterBinderProviderConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'org.cache2k.Cache2kBuilder', 'org.cache2k.extra.spring.SpringCache2kCache', 'org.cache2k.extra.micrometer.Cache2kCacheMetrics' (OnClassCondition)

CacheMeterBinderProvidersConfiguration.CaffeineCacheMeterBinderProviderConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.github.benmanes.caffeine.cache.Cache' (OnClassCondition)

CacheMeterBinderProvidersConfiguration.HazelcastCacheMeterBinderProviderConfiguration:
Did not match:
- @ConditionalOnClass did not find required classes 'com.hazelcast.spring.cache.HazelcastCache',  'com.hazelcast.core.Hazelcast' (OnClassCondition)

CacheMeterBinderProvidersConfiguration.JCacheCacheMeterBinderProviderConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.cache.CacheManager' (OnClassCondition)

CacheMeterBinderProvidersConfiguration.RedisCacheMeterBinderProviderConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.data.redis.cache.RedisCache' (OnClassCondition)

CachesEndpointAutoConfiguration:
Did not match:
- @ConditionalOnAvailableEndpoint not exposed (OnAvailableEndpointCondition)
Matched:
- @ConditionalOnClass found required class 'org.springframework.cache.CacheManager' (OnClassCondition)

CaffeineCacheConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.github.benmanes.caffeine.cache.Caffeine' (OnClassCondition)

CassandraAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.datastax.oss.driver.api.core.CqlSession' (OnClassCondition)

CassandraDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.datastax.oss.driver.api.core.CqlSession' (OnClassCondition)

CassandraHealthContributorAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.datastax.oss.driver.api.core.CqlSession' (OnClassCondition)

CassandraReactiveDataAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.datastax.oss.driver.api.core.CqlSession' (OnClassCondition)

CassandraReactiveHealthContributorAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.datastax.oss.driver.api.core.CqlSession' (OnClassCondition)

CassandraReactiveRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.springframework.data.cassandra.ReactiveSession' (OnClassCondition)

CassandraRepositoriesAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'com.datastax.oss.driver.api.core.CqlSession' (OnClassCondition)

Exclusions:
-----------
None

Unconditional classes:
----------------------
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
org.springframework.boot.actuate.autoconfigure.availability.AvailabilityHealthContributorAutoConfiguration
org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration
org.springframework.boot.actuate.autoconfigure.info.InfoContributorAutoConfiguration
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.integration.IntegrationMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration
org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration
org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsAutoConfiguration
org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration
org.springframework.boot.actuate.autoconfigure.endpoint.jackson.JacksonEndpointAutoConfiguration
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
Как использовать Vertex ai embedder вообще и model=text-embedding-005 в частности? Что я делаю не так?

Подробнее здесь: https://stackoverflow.com/questions/798 ... g-boot-app
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»