Spring STS - unable to resolve properties - eclipse

This question is not related with spring, but with STS tool suite or with spring eclipse IDE. Given following declaration of the class
#Configuration()
#Import({ WebSharedConfig.class, SpringSecurityConfig.class })
#ComponentScan({ "com.finovera.web", "com.finovera.platformServices","com.finovera.authentication" })
#PropertySources(value = { #PropertySource({ "${FINOVERA_PROPERTIES}" }),
#PropertySource(value = { "${STATIC_OVERRIDE_PROPERTIES}", }, ignoreResourceNotFound = true) })
#Scope("singleton")
#EnableTransactionManagement
public class CabinetConfig extends WebMvcConfigurationSupport {
}
I am seeing following exception in STS plugin (org.springframework.ide.eclipse.beans.core)
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.finovera.web.config.CabinetConfig]; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'FINOVERA_PROPERTIES' in string value "${FINOVERA_PROPERTIES}"
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:181)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:321)
Error is simple as properties name is passed to JVM when application starts. The application run time code works fine, but STS does not. Lot of functionality missing as main configuration scan fails. Commenting out property sources annotation, everything works fine.
How do I pass property value to STS or convince it to ignore PropertySources annotation?

I think this is a limitation in the current implementation. Please file an enhancement request against: https://issuetracker.springsource.com/browse/STS and we can try to fix this for the next release of STS and Spring IDE.

Related

SpringBootTest + JPA + Kafka - context is not loading properly during testing

I have Spring Boot application with kafka and jpa in it. I am using h2 as my in-memory database. For each test class execution, I don't want kafka to come up for each test class. I have 2 test classes, one is KafkaConsumerTest and another one is JPATest. KafkaConsumerTest is annotated with #SpringBootTest and it perfectly loads the entire application and passes all the test. However, for JPATest, I don't want to bring up the entire application and just few desired context to test out JPA related changes. When I do that, it is throwing the following exception.
Caused by: java.lang.IllegalArgumentException: dataSource or dataSourceClassName or jdbcUrl is required.
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:958)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:109)
at org.eclipse.persistence.sessions.JNDIConnector.connect(JNDIConnector.java:138)
at org.eclipse.persistence.sessions.DatasourceLogin.connectToDatasource(DatasourceLogin.java:172)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.setOrDetectDatasource(DatabaseSessionImpl.java:233)
at org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.loginAndDetectDatasource(DatabaseSessionImpl.java:815)
at org.eclipse.persistence.internal.jpa.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:256)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:769)
I am passing the datasource with jdbcUrl in my application.yml file
src/test/resources/application.yml
spring:
datasource:
jdbcUrl: jdbc:h2:mem:mydb
url: jdbc:h2:mem:mydb
driverClassName: org.h2.Driver
username: sa
kafka:
bootstrap-servers: ${spring.embedded.kafka.brokers}
KafkaConsumerTest.java
#RunWith(SpringRunner.class)
#SpringBootTest (classes = Application.class)
#DirtiesContext
#EmbeddedKafka(partitions = 1,
topics = {"${kafka.topic}"})
public class KafkaConsumerTest {
JpaTest.java
#RunWith(SpringRunner.class)
#ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class, classes = {JPAConfiguration.class})
public class NotificationServiceTest {
I tried putting loader as AnnotationConfigContextLoader.class but it gave me the same error. I tried specifying application.yml exclusively using TestPropertyResource but still the same error.
#TestPropertyResource(locations = {"classpath:application.yml"})
I think I am not able to load the context properly here and application.yml file is not able to pick or parse values here.
Any suggestions on how to resolve this.
I am able to solve the issue. The reason of this issue was spring context was not getting loaded properly for other tests as I was not using #SpringBootTest. How I bypassed the error and also loading the spring boot context only for one time was to create a base class like this.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = Application.class)
#DirtiesContext
#EmbeddedKafka(partitions = 1,
topics = {"${kafka.topic}"})
public abstract class AbstractSpringBootTest {
}
Now every test class has to extend this class as per the following code. This way spring test will be loaded once only provided the context doesn't get changed during the tests run.
public class MyTest extends AbstractSpringBootTest {
Posting the solution which worked for me for other people's reference.

Springboot postgres Failed to determine a suitable driver class

I am trying to develop web application using SpringBoot and Postgres Database. However, on connecting to the application, I am getting error "Failed to determine a suitable driver class"
As per advise in older posts, I have tried using driver of different version of jdbc and also tried creating bean for NamedParameterJdbcTemplate manually. I also validated that libraries are present and is accessible from Java code and those are present in classpath. But its still giving the same issue.
I am using gradle to import all jars into build path.
Here is the git repository for the code:
https://github.com/ashubisht/sample-sbs.git
Gradle dependency code:
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-websocket")
compile("org.springframework.boot:spring-boot-starter-jdbc")
//compile("org.postgresql:postgresql")
compile("org.postgresql:postgresql:9.4-1206-jdbc42")
testCompile("org.springframework.boot:spring-boot-starter-test")
testCompile group: 'junit', name: 'junit', version: '4.12'
}
Code for building Bean
#Configuration
#PropertySource("classpath:application.properties")
public class Datasource {
#Value("${db.driverClassName}")
private String driverClass;
#Value("${db.url}")
private String url;
#Value("${db.username}")
private String username;
#Value("${db.password}")
private String password;
#Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() throws Exception{
System.out.println(driverClass+" "+ url+" "+username+" "+password);
DriverManagerDataSource source = new DriverManagerDataSource();
source.setDriverClassName(driverClass);
source.setUrl(url);
source.setUsername(username);
source.setPassword(password);
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(source);
return namedParameterJdbcTemplate;
}
}
Here is application.properties
server.port=8086
#spring.datasource.driverClassName=org.postgresql.Driver
#spring.datasource.url= jdbc:postgresql://localhost:5432/testdb
#spring.datasource.username=postgres
#spring.datasource.password=password
#spring.datasource.platform=postgresql
#spring.jpa.hibernate.ddl-auto=create-drop
db.driverClassName=org.postgresql.Driver
db.url=jdbc:postgresql://localhost:5432/testdb
db.username=postgres
db.password=password
The issue is resolved by creating two beans. Separate bean is created for DataSource and NamedParameterJdbcTemplate.
#Bean
public DataSource dataSource(){
System.out.println(driverClass+" "+ url+" "+username+" "+password);
DriverManagerDataSource source = new DriverManagerDataSource();
source.setDriverClassName(driverClass);
source.setUrl(url);
source.setUsername(username);
source.setPassword(password);
return source;
}
#Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(){
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(this.dataSource());
return namedParameterJdbcTemplate;
}
For me the issue was in a miss-spell for postgresSql
its only one s,
replace
spring.datasource.url=jdbc:postgres://localhost:5432/databaseName
spring.datasource.url=jdbc:postgressql://localhost:5432/databaseName
with
spring.datasource.url=jdbc:postgresql://localhost:5432/databaseName
also check the same thing on hibernate dialect,
replace PostgresSQLDialect
with PostgreSQLDialect
Had the same problem.
The solution for me was to change application.properties file extension into application.yml
For me the error was
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put
it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
and the issue was missing profile
so I added the following in the classpath and it worked
spring.profiles.active=dev
Please try it
spring.r2dbc.url=r2dbc:postgresql://ip:port/datafeed?currentSchema=user_management
spring.r2dbc.username=username
spring.r2dbc.password=12345
spring.r2dbc.driver=postgresql
Hope to help you!
I got the same error. It happens when you install sts version 3.
I found the solution to this problem by doing trial & error method.
This error is occured due to the non-availability of the connection between Application Properties & the server. I got to know by changing the port number in the application Properties to 9090, later then while running the application the console showed the default port number 8080.
Thus you should maven clean and maven build your Spring Boot Application.
After the above step, you run your application normally as spring boot application, the database will get connected and the application will get started.

UnknownServiceException: Unknown service requested [EnversService]

I want to run Hibernate in OSGi. I have added the standard Hibernate OSGi bundle and a Blueprint implementation, so that Envers gets registered right on startup.
Even without any kind of documentation I found out you have to start Envers, because... I doubt there is a logical reason, it does not work otherwise.
However now, even though Envers was registered in Blueprint, I get the following exception:
org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.envers.boot.internal.EnversService]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:184)
at org.hibernate.envers.boot.internal.TypeContributorImpl.contribute(TypeContributorImpl.java:22)
at org.hibernate.boot.internal.MetadataBuilderImpl.applyTypes(MetadataBuilderImpl.java:280)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.populate(EntityManagerFactoryBuilderImpl.java:798)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:187)
at org.hibernate.jpa.boot.spi.Bootstrap.getEntityManagerFactoryBuilder(Bootstrap.java:34)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilder(HibernatePersistenceProvider.java:165)
at org.hibernate.jpa.HibernatePersistenceProvider.getEntityManagerFactoryBuilderOrNull(HibernatePersistenceProvider.java:114)
at org.hibernate.osgi.OsgiPersistenceProvider.createEntityManagerFactory(OsgiPersistenceProvider.java:78)
at org.acme.project.Main.startSession(PersistenceUnitJpaProvider.java:38)
The stack trace starts at PersistenceProvider#createEntityManagerFactory in the following snippet:
public class Main {
private EntityManagerFactory entityManagerFactory;
public void startSession(Map<String, Object> config) {
BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
ServiceReference<PersistenceProvider> serviceReference = context.getServiceReference(PersistenceProvider.class);
PersistenceProvider persistenceProvider = context.getService(serviceReference);
this.entityManagerFactory = persistenceProvider.createEntityManagerFactory("persistenceUnit", config);
context.ungetService(serviceReference);
}
I found this bug, and maybe this issue is fixed in the current version of Hibernate. But since the bundle IDs are broken, I have to use 5.1.
So Envers is registered, but not really. What could be the reason for such a strange error message?

Autowiring issues with a class in Spring data Mongo repository

For a variety of reasons, I ended up using spring boot 1.2.0 RC2.
So a spring data mongo application that worked fine in spring boot1.1.8 is now having issues. No code was changed except for the bump to spring boot 1.2.0 RC2. This is due to the snapshot version of spring cloud moving to this spring boot version.
The repository class is as follows
#Repository
public interface OAuth2AccessTokenRepository extends MongoRepository<OAuth2AuthenticationAccessToken, String> {
public OAuth2AuthenticationAccessToken findByTokenId(String tokenId);
public OAuth2AuthenticationAccessToken findByRefreshToken(String refreshToken);
public OAuth2AuthenticationAccessToken findByAuthenticationId(String authenticationId);
public List<OAuth2AuthenticationAccessToken> findByClientIdAndUserName(String clientId, String userName);
public List<OAuth2AuthenticationAccessToken> findByClientId(String clientId);
}
This worked quite well before the bump in versions and now I see this in the log.
19:04:35.510 [main] DEBUG o.s.c.a.ClassPathBeanDefinitionScanner - Ignored because not a concrete top-level class: file [/Users/larrymitchell/rpilprojects/corerpilservicescomponents/channelMap/target/classes/com/cisco/services/rpil/mongo/repository/oauth2/OAuth2AccessTokenRepository.class]
I do have another mongo repository that is recognized but it was defined as a class implementation
#Component
public class ChannelMapRepository { ... }
This one is recognized (I defined it as a implementation class as a workaround for another problem I had). This class is recognized and seems to work fine.
19:04:35.513 [main] DEBUG o.s.c.a.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/larrymitchell/rpilprojects/corerpilservicescomponents/channelMap/target/classes/com/cisco/services/rpil/services/Microservice.class]
Anyone have an idea why? I looked up the various reasons for why component scanning would not work and nothing lends itself to my issue.
Try removing the #Repository annotation? Worked for me. This was an issue in Github as well.

Injecting EJB within JAX-RS resource in JBoss 5

Although there already are quite some StackOverflow questions, blog entries, etc. on the web, I still cannot figure out a solution to the problem stated below.
Similar to this question (Injecting EJB within JAX-RS resource on JBoss7) I'd like to inject a EJB instance into a JAX-RS class. I tried with JBoss 5, JBoss 7, and WildFly 8. I either get no injection at all (field is null), or the server does not deploy (as soon as I try to combine all sorts of annotations).
Adding #Stateless to the JAX-RS makes the application server know both classes as beans. However, no injection takes place.
Is there a way to inject EJBs into a REST application? What kind of information (in addition to that contained in the question linked to above) could I provide to help?
EDIT: I created a Github project showing code that works (with Glassfish 4.0) and does not work (with JBoss 5).
https://github.com/C-Otto/beantest
Commit 4bf2f3d23f49d106a435f068ed9b30701bbedc9d works using Glassfish
4.0.
Commit 50d137674e55e1ceb512fe0029b9555ff7c2ec21 uses Jersey 1.8, which does not work.
Commit 86004b7fb6263d66bda7dd302f2d2a714ff3b939
uses Jersey 2.6, which also does not work.
EDIT2:
Running the Code which I tried on JBoss 5 on Glassfish 4.0 gives:
Exception while loading the app : CDI deployment failure:WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)]
org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [Ref<ContainerRequest>] with qualifiers [#Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor] #Inject org.glassfish.jersey.server.internal.routing.UriRoutingContext(Ref<ContainerRequest>, ProcessingProviders)]
at org.jboss.weld.bootstrap.Validator.validateInjectionPointForDeploymentProblems(Validator.java:403)
EDIT3: The crucial information might be that I'd like a solution that works on JBoss 5
If you don't want to make your JAX-RS resource an EJB too (#Stateless) and then use #EJB or #Resource to inject it, you can always go with JNDI lookup (I tend to write a "ServiceLocator" class that gets a service via its class.
A nice resource to read about the topic:
https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project
A sample code:
try {
// 1. Retreive the Home Interface using a JNDI Lookup
// Retrieve the initial context for JNDI. // No properties needed when local
Context context = new InitialContext();
// Retrieve the home interface using a JNDI lookup using
// the java:comp/env bean environment variable // specified in web.xml
helloHome = (HelloLocalHome) context.lookup("java:comp/env/ejb/HelloBean");
//2. Narrow the returned object to be an HelloHome object. // Since the client is local, cast it to the correct object type.
//3. Create the local Hello bean instance, return the reference
hello = (HelloLocal)helloHome.create();
} catch(NamingException e) {
} catch(CreateException e) {
}
This is not "injecting" per-se, but you don't use "new" as-well, and you let the application server give you an instance which is managed.
I hope this was useful and I'm not telling you something you already know!
EDIT:
This is an excellent example: https://docs.jboss.org/author/display/AS72/EJB+invocations+from+a+remote+client+using+JNDI
EDIT 2:
As you stated in your comment, you'd like to inject it via annotations.
If the JNDI lookup is currently working for you without problems, and
If you're using Java EE 6+ (which I'm guessing you are), you can do the following:
#EJB(lookup = "jndi-lookup-string-here")
private RemoteInterface bean;