The path to the driver executable must be set - spring

Controller
#Controller
#RequestMapping
#AllArgsConstructor
public class HomeController {
private final ParseData parseArsenkin;
#GetMapping("/")
public String getHome(){
return "home";
}
#PostMapping("/")
public String postHome(){
parseArsenkin.parse();
return "result";
}
}
WebDriverConfig.java
#Configuration
public class WebDriverConfig {
#Bean
public FirefoxDriver firefoxDriver() {
WebDriverManager.firefoxdriver().setup();
return new FirefoxDriver();
}
}
ParseData.java
#Service
#AllArgsConstructor
public class ParseData {
private final FirefoxDriver firefoxDriver;
public void parse() {
String baseUrl = "http://google.com";
firefoxDriver.get(baseUrl);
System.out.println();
}
}
Error
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'homeController' defined in file [/home/michael/Documents/JavaProjects/positions/target/classes/ru/pcask/positions/controller/HomeController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'parseArsenkin' defined in file [/home/michael/Documents/JavaProjects/positions/target/classes/ru/pcask/positions/service/ParseArsenkin.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'firefoxDriver' defined in class path resource [ru/pcask/positions/configuration/WebDriverConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.openqa.selenium.firefox.FirefoxDriver]: Factory method 'firefoxDriver' threw exception; nested exception is java.lang.IllegalStateException: The path to the driver executable The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver. The latest version can be downloaded from https://github.com/mozilla/geckodriver/releases
I tried to follow this tutorial: https://www.baeldung.com/java-selenium-webdriver-path-error#automated-setup
According to the tutorial I don't have to provide geckodriver manually.
What have I done wrongly?

add in WebDriverConfig System.setProperty("webdriver.gecko.driver","src/main/resources/geckodriver.exe" );

Related

Java AWS SDK v2 S3Client creation fail

I'm try to use S3Client from AWS Java SDK v2, on my JHipster Spring boot project.
In addition to S3CLient i'm using S3Presigner for pre-signed url generation.
This is the configuration class, that i'm using to create beans:
#Configuration
public class AWSConfiguration {
private final Logger log = LoggerFactory.getLogger(AWSConfiguration.class);
#Bean(name = "credentialsProvider")
public AwsCredentialsProvider getCredentialsProvider(#Value("${aws.accessKey}") String accessKey, #Value("${aws.secretKey}") String secretKey) {
return StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey));
}
#Bean(name = "presigner")
#Primary
public S3Presigner getPresigner(#Value("${aws.region}") String awsRegion, #Qualifier("credentialsProvider") final AwsCredentialsProvider credentialsProvider) {
return S3Presigner.builder().credentialsProvider(credentialsProvider).region(Region.of(awsRegion)).build();
}
#Bean(name = "s3Client")
#Primary
public S3Client getS3Client(#Value("${aws.region}") String awsRegion, #Qualifier("credentialsProvider") final AwsCredentialsProvider credentialsProvider) {
return S3Client.builder().credentialsProvider(credentialsProvider).region(Region.of(awsRegion)).build();
}
}
At the boot, i've this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 's3Client' defined in class path resource [com/cyd/bb/config/AWSConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [software.amazon.awssdk.services.s3.S3Client]: Factory method 'getS3Client' threw exception; nested exception is java.lang.IllegalArgumentException: Expected a profile or property definition on line 1
If i remove "s3Client" bean the project start correctly and i can use presigner without problems.
So s3Client produce the error, someone can help me for this issue?
Thanks in advance.

Using Prototype scope to create DataSource

I'm trying to create a Prototyped Scoped Spring bean using the given configuration. The details for url, username, password, driver will be determined at runtime. Here's my configuration:
#Configuration
class Cfg {
#Bean
public Function<DataSourcePropertiesMap, DriverManagerDataSource> functionOfDriverMgrDS() {
return this::driverManagerDataSource;
}
#Lazy
#Bean
#Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public DriverManagerDataSource driverManagerDataSource(DataSourcePropertiesMap dbPropsMap) {
var ds = new DriverManagerDataSource(dbPropsMap.getDbURL(), dbPropsMap.getDbUsername(), dbPropsMap.getDbPassword());
ds.setDriverClassName(dbPropsMap.getDbDriver());
return ds;
}
}
And the DataSourcePropertiesMap is simply a container for the four arguments as below:
#Getter
#AllArgsConstructor
public class DataSourcePropertiesMap {
#NonNull private final String dbURL;
#NonNull private final String dbUsername;
#NonNull private final String dbPassword;
#NonNull private final String dbDriver;
}
Whenever, I boot the application it throws the following exception:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthContributorRegistry' defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]: Unsatisfied dependency expressed through method 'healthContributorRegistry' parameter 2; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dbHealthContributor' defined in class path resource [org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.class]: Unsatisfied dependency expressed through method 'dbHealthContributor' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'driverManagerDataSource' defined in class path resource [Cfg.class]: Unsatisfied dependency expressed through method 'driverManagerDataSource' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'DataSourcePropertiesMap' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Why Spring still requires arguments for DriverManagerDataSource with valid driver class for Prototyped Scoped beans. My assumption is it will register a bean someway and create a new instance whenever a call is made with the arguments. If I create a default bean of type DataSourcePropertiesMap with dummy values it requires a valid driverclass.
Editing my original answer since I have not seen this part of the question
The details for url, username, password, driver will be determined at
runtime.
As of spring boot 2.x there is still no automatic way of loading properties on runntime. You would have to manually parse the file and read those properties inside this prototype bean method.

#WebMvcTest not running due to missing dependency

I want to test my controller by using #WebMvcTest. I #MockBean the dependencies of the controller but when running the test, it fails to start. The application starts correctly when running the main class.
The Test:
#RunWith(SpringRunner.class)
#WebMvcTest(MetricResource.class)
public class MetricResourceTest {
#Autowired
private MockMvc mvc;
#MockBean
private MetricService metricService;
#MockBean
private MetricMapper metricMapper;
#Test
public void test() {
}
}
The Controller:
#RestController
#RequestMapping("/api/v1/metrics")
public class MetricResource {
private final MetricService metricService;
private final MetricMapper metricMapper;
public MetricResource(MetricService metricService, MetricMapper metricMapper) {
this.metricService = metricService;
this.metricMapper = metricMapper;
}
#GetMapping
public ResponseEntity<List<MetricDto>> getMetrics(#RequestParam(required = false) List<String> fields) {
if (fields == null) {
fields = new ArrayList<>();
}
List<Metric> metrics = metricService.getMetric(fields);
List<MetricDto> dto = metricMapper.fromMetric(metrics);
return ResponseEntity.ok(dto);
}
}
The error:
Description:
Parameter 2 of constructor in com.sps.soccer.service.SoccerService required a bean named 'mongoTemplate' that could not be found.
Action:
Consider defining a bean named 'mongoTemplate' in your configuration.
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'soccerService' defined in file [K:\home\projects\stable\sps-backend\sps-soccer\target\classes\com\sps\soccer\service\SoccerService.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soccerAnalysisRepository': Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soccerAnalysisRepository': Cannot resolve reference to bean 'mongoTemplate' while setting bean property 'mongoOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'mongoTemplate' available
The SoccerService has a dependency on SoccerAnalysisRepository which is a MongoRepository. I don't understand why the SoccerService is created by the test since #Service are not scanned by #WebMvcTest.
The application is a Maven multi modules, so I has to explicitly configure the component scanning and repository.
#SpringBootApplication
#ComponentScan(basePackages = {"com.sps.soccer", "com.sps.sdql", "com.sps.core", "com.sps.web"},
excludeFilters = {
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = com.sps.sdql.configuration.ClockConfiguration.class),
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = com.sps.soccer.configuration.ClockConfiguration.class),
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = com.sps.sdql.configuration.RestConfiguration.class),
#ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = com.sps.soccer.configuration.RestConfiguration.class)
})
#EnableMongoRepositories(basePackages = {"com.sps.soccer", "com.sps.sdql", "com.sps.core"})
public class SpsWebApplication {
public static void main(String[] args) {
SpringApplication.run(SpsWebApplication.class, args);
}
}
You must move all area-specific configuration, like #ComponentScan and #EnableMongoRepositories, to a separate #Configuration file. It's important not to litter the application’s main class with configuration settings that are specific to a particular area of its functionality.
More information: https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-user-configuration

how to config mybatis in springboot

I have two config here:
#Configuration
public class DataConfig {
#Value("${datasource.jdbcUrl}")
private String jdbcUrl;
#Value("${datasource.username}")
private String username;
#Value("${datasource.password}")
private String password;
#Value("${datasource.driverClassName:com.mysql.jdbc.Driver}")
private String driverClassName;
#Value("${datasource.initialSize:20}")
private int initialSize;
#Value("${datasource.maxActive:30}")
private int maxActive;
#Value("${datasource.minIdle:20}")
private int minIdle;
#Value("${datasource.transactionTimeoutS:30}")
private int transactionTimeoutS;
#Value("${datasource.basePackage:com.tg.ms.mapper}")
private String basePackage;
#Value("${datasource.mapperLocations}")
private String mapperLocations;
#Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setMaxWait(maxWait);
ds.setValidationQuery(validationQuery);
ds.setRemoveAbandoned(removeAbandoned);
ds.setRemoveAbandonedTimeout(removeAbandonedTimeout);
ds.setTestWhileIdle(testWhileIdle);
ds.setTestOnReturn(testOnReturn);
ds.setTestOnBorrow(testOnBorrow);
ds.setMinIdle(minIdle);
return ds;
}
#Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mybatis/*.xml"));
return sqlSessionFactoryBean.getObject();
}
---------- Another Config -------------
#Configuration
#AutoConfigureAfter(DataBaseConfig.class)
public class MapperScannerConfig {
#Value("${datasource.basePackage:com.tg.ms.mapper}")
private String basePackage;
#Bean
public MapperScannerConfigurer BPMapperScannerConfigurer() {
System.out.println("mapper--1.----******----"+basePackage+"----*******");
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.tg.mapper");
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
return mapperScannerConfigurer;
}
}
Can I put#Bean public MapperScannerConfigurer BPMapperScannerConfigurer() into DataConfig? I try but print:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testController': Unsatisfied dependency expressed through field 'testMapper'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testMapper' defined in file [/Users/twogoods/codesource/mainetset/target/classes/com/tg/mapper/TestMapper.class]: Cannot resolve reference to bean 'sqlSessionFactoryBean' while setting bean property 'sqlSessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactoryBean' defined in class path resource [com/tg/config/DataConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.ibatis.session.SqlSessionFactory]: Factory method 'sqlSessionFactoryBean' threw exception; nested exception is java.lang.NullPointerException
MapperScannerConfig init earlier than DataConfig, I get it from print log,#Value("${datasource.basePackage:com.tg.ms.mapper}") private String basePackage;can not get value(in DataConfig can get),I use #AutoConfigureAfter is useless,MapperScannerConfig is also eariler, I can not config mapper basePackage
log:Cannot enhance #Configuration bean definition 'BPMapperScannerConfigurer' since its singleton instance has been created too early. The typical cause is a non-static #Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as 'static'.
I got the same problem. MapperScannerConfigurer is initialized too early in spring framework and ,i think it causes the annotation #AutoConfigureAfter become useless.
So i solve it like : avoid the use of MapperScannerConfigurer:
two ways:
just use #MapperScan("com.a.b.package")
use annotation #org.apache.ibatis.annotations.Mapper in your mybatis mapper interface.

Cucumber Spring and class configuration

I'm struggling with Cucumber and Spring configuration.
I'm writing selenium framework using Page Object Pattern, with BrowserFactory.
When I use #ComponentScan, #Component and #Autowire annotations everything works fine, but when I want to create a bit more complicated bean with #Bean annotation (BrowserFactory which registers few browser drivers) in #Configuration class it does not work, during debug I'm getting nulls on every single variable I'm trying to Autowire.
I'm using Spring 4.2.4, all cucumber dependencies in version 1.2.4.
Config:
#Configuration
public class AppConfig {
#Bean
#Scope("cucumber-glue")
public BrowserFactory browserFactory() {
BrowserFactory browserFactory = new BrowserFactory();
browserFactory.registerBrowser(new ChromeBrowser());
browserFactory.registerBrowser(new FirefoxBrowser());
return browserFactory;
}
#Bean(name = "loginPage")
#Scope("cucumber-glue")
public LoginPage loginPage() throws Exception {
return new LoginPage();
}
#Bean(name = "login")
#Scope("cucumber-glue")
public Login login() {
return new Login();
}
}
POP:
public class LoginPage extends Page {
public LoginPage() throws Exception {
super();
}
...
}
Page:
public class Page {
#Autowired
private BrowserFactory browserFactory;
public Page() throws Exception{
...
}
}
Login:
public class Login {
#Autowired
private LoginPage loginPage;
public Login(){}
...
}
Steps:
#ContextConfiguration(classes = {AppConfig.class})
public class LoginSteps {
#Autowired
Login login;
public LoginSteps(){
}
#Given("^an? (admin|user) logs in$")
public void adminLogsIn(Login.User user) throws Exception {
World.currentScenario().write("Logging in as " + user + "\n");
login.as(user);
}
}
Error:
cucumber.runtime.CucumberException: Error creating bean with name 'LoginSteps': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: Login LoginSteps.login; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'login': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private LoginPage Login.loginPage; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginPage' defined in AppConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [LoginPage]: Factory method 'loginPage' threw exception; nested exception is java.lang.NullPointerException
And now for the fun part...
BrowserFactory in World class is properly Autowired!!
World:
public class World {
#Autowired
private BrowserFactory browserFactory;
...
}
So I'll answer my own question:)
Issue was that I was calling BrowserFactory inside of Page constructor.
Looks like this bean was not yet created and was causing NPEs.
In order to fix that I:
Added #Lazy annotation to configuration (all elements that use this configuration, both defined in that class and those which will be found by Scan will be created as Lazy)
Moved call to Browser Factory to #PostConstruct method
Two more things to increase readability of Spring config:
Added #ComponentScan to configuration
Classes with no constructor parameters are annotated with #Component and #Scope("cucumber-glue") annotation so bean creation can be removed from AppConfig.class

Resources