Sending Email using VSCode (spring-boot-starter-email) - java

I am implementing how to send email using spring boot
I am trying to implement this in visual studio code.
But it gives me the following error
I added the following two dependencies in my pom.xml for email configuration:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
my main bootstrap class:
#SpringBootApplication
#ComponentScan(basePackages = {
"email"
})
public class Application {
public static void main(String[] args) {
Mail mail = new Mail();
mail.setMailFrom("abc#gmail.com");
mail.setMailTo("xyz#gmail.com");
mail.setMailSubject("Hi");
mail.setMailContent("Hope you are doing well");
ApplicationContext ctx = SpringApplication.run(Application.class,
args);
MailService mailService = (MailService) ctx.getBean("mailService");
mailService.sendEmail(mail);
}
I think my error is related to the #ComponentScan(basePackages = {"email"}) annotation that I have used above
Can anyone help me with the error?

Since we don't know the package structure it is difficult to tell what should be there in the basePackages inside #ComponentScan
Firstly, please move your Application class to one level up in the package structure, so that it reads all packages under it by default and remove the basePackages in component scan. So, it should be just #ComponentScan
That is, if all your classes are in package com.test.mailer then your Application class file should be in com.test
Try this and let us know, also I hope you have the #Service annotation as #Service("mailService")
Update:
Since the user has updated the question later, I am posting the solution that worked for him.
He moved the class one level up and removed the basePackages and it worked for him. As stated in the first part of my answer.
Alternatively, he could have changed #ComponentScan(basePackages = {"email"}) to #ComponentScan("java.risknucleus") in the same structure.

Related

How to access a controller or a component from one directory to another in Spring Boot?

Tried to access a controller from a parent directory. I have used this method to call it from a child directory.
<dependency>
<groupId>com.sample</groupId>
<artifactId>sample-core</artifactId>
</dependency
Here is the error for the above usage
[ERROR] /D:/Projects/sample/src/main/java/com/sample/controllers/abcController.java
package com.sample.controller does not exist
Any help is appreciated to help me get access from a parent or a different directory.
you need to show to spring that contains other classes to scan beyond your current project
I think you are looking for #ComponentScan(basePackages={"com.sample"}) that tells to spring see your third-party packages
#SpringBootApplication
#EntityScan(basePackages = {"br.com.scan-others-entities-in-other-projects"})
#ComponentScan(basePackages = {"br.com.my-curent-project", "br.com.scan-other-configs-and-controllers"})
#EnableJpaRepositories(basePackages = {"br.com.com-other-repositories"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

#Value("${local.server.port}") not working in Spring boot 1.5

I am upgrading Spring Boot from 1.3 to 1.5. For upgrading to 1.5 I have replaced
#SpringApplicationConfiguration(classes = TestConfig.class)
#WebIntegrationTest
with
#SpringBootTest(classes = TestConfig.class)
Also, I am using
#Value("${local.server.port}")
protected int port;
to get port number defined in application.properties file. I further use this port number to build a REST URL.
But after the upgrade I am getting the error below whereas the same works fine with 1.3 Spring Boot Test.
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'local.server.port' in value "${local.server.port}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
Am I missing any changes that I need to do for this to work.
You have to provide a value for webEnvironment. In your case DEFINED_PORT like this
#SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.DEFINED_PORT)
public class YourTest {
#LocalServerPort // shorthand for #Value("${local.server.port}")
private Integer port;
...
}
For details see: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications
Adding another alternate solution which I had elsewhere.
I had configured
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
and
#RunWith(SpringRunner.class)
#SpringBootTest(classes = App.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class YourTest {
#LocalServerPort // shorthand for #Value("${local.server.port}")
private Integer port;
...
}
Thinking that was it, and still getting this error even when specifying web environment etc. My ${local.server.port} seemed to be always null.
After some time, I noticed that my Spring Boot startup message contained no notion of the port it was using, so apparently it really didn't listen to any port at all - which explained why it was null in the first place. Adding actual container implementation dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
Caused this to appear on my logs:
2019-02-26 18:45:47.231 INFO 12504 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 43132 (http/1.1) with context path '/'
after which local.server.port and #LocalServerPort would also work.
For me the problem was that there was alternative #Configuration class(es) in my other test(s) like this:
#Configuration
public class ReadPropertiesConfiguration {
#Bean
PropertyPlaceholderConfigurer propConfig() {
PropertyPlaceholderConfigurer placeholderConfigurer = new PropertyPlaceholderConfigurer();
placeholderConfigurer.setLocation(new ClassPathResource("application.properties"));
return placeholderConfigurer;
}
}
and #SpringBootApplication of the app was picking that up due to its #ComponentScan, and for some reason it resulted in this problem. When adding exclusion for those and/or replacing them with other solutions things started again to work without problems.
I don't know the root cause why this happens, but that might be your issue as well.
First make sure the property is correctly spelled in the properties file. As i did just few days back using spring-boot-1.5.2 & it works.
Or
You need to add
#PropertySource("classpath:application.properties")
to your class, so it will pick your configurations.
If you need different configurations for test you can add
#TestPropertySource(locations="classpath:test.properties")
Refer #Value not work on Spring Boot Test

Use mysql instead hsql java spring

I hava this codes and i use application.properties for use mysql but yet hsql is use.
application.properties
spring.datasource.url=jdbc:mysql://localhost:3307/dvv
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.platform=mysql
and application.class
#EnableAutoConfiguration
#EnableJpaRepositories(basePackageClasses = {VideoRepository.class, VideoRepository2.class})
#Configuration
#EnableWebMvc
#ComponentScan
public class Application {
// Tell Spring to launch our app!
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
and Repository
#Repository
public interface VideoRepository2 extends CrudRepository<Video2, Long>{
// Find all videos with a matching title (e.g., Video.name)
public Collection<Video2> findByName(String title);
// Find all videos within a given category
public Collection<Video2> findByCategory(String category);
}
Can you verify,
1.Check how many application-XXX.properties files are exists in your application.
2.Check whether you are using correct profile to run this application.
Also share your hsql configuration as well.
make sure the mysql connector is added to your pom.xml /build.gradle
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

How to call a Spring managed object from a POJO?

I am running a web-app, which has one exposed class ( available to other POJO classes) and that has one autowired private member.
Spring managed class
public class EPSQueueSender {
#Autowired
private AmqpTemplate epsMessageTemplate;
public void dosomething(...){
epsMessageTemplate.convertAndSend(...); // Here epsMessageTemplate is null if instance of EPSQueueSender taken from other POJO
}
}
POJO class
public class Test{
EPSQueueSender sender = new EPSQueueSender();
sender.dosomething(....); // gives null exception on epsMessageTemplate
}
Spring code ( running as WebApp) and POJO class code( different Jar) are on same JVM. The POJO is not able to get initialized autowired object. However it is initialized if I use it in webApp project.
Can someone please give some suggestion how can I overcome this problem?
Last thing I would like to try is to hit webserver as http request from POJO.
beans can be pojo or xml many examples might help. You already have #autowired but you did not create the #bean method itself that belongs in a class annotated with #Configuration
Your problem could be overcome using #Configurable feature of spring. For it you have configure in xml with a code like belove
<context:annotation-config/>
<context:spring-configured/>
<context:load-time-weaver/>
in Java Congiguration like below:
#Configuration
#EnableAspectJAutoProxy
#EnableSpringConfigured
#EnableLoadTimeWeaving
public class ConfigApplicationContext {
}
with this configuration you can benefit of the load-waving aspect technique that througth the build-in Spring bean AnnotationBeanConfigureAspect you can inject Spring bean in a pojo that is annotated with #Configurable. you colud be have a code like below:
#Configurable
public class Test{
#Autowired
private EPSQueueSender sender;
public void method(){
sender.dosomething(....); // gives null exception on epsMessageTemplate
}
}
of course, since that you are using a load-wave technique you have configure an agent that will perform the istruments. the configuration is very simple and you have add a line like below in the start of the jvm or tomcat:
java -javaagent:path of the jar with the agent/spring-instrument.jar
remember of course of insert the aop and spring aop maven dependency:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>yourVersion</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>4
<version>yourVersion</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>yourVersion</version>
</dependency>
I hope that this can help you

Unit test with testNG in spring boot takes time to build project

I have created a web application in spring-boot. I am writing a unit tests with testNG for my business layer.
I have created Application class
#SpringBootApplication
public class TestApplication
{
public static void main(String[] args)
{
SpringApplication.run(TestApplication.class, args);
}
#Bean
Mapper mapper()
{
List<String> mappingFiles = new ArrayList<String>();
mappingFiles.add("dozer-mappings.xml");
return new DozerBeanMapper(mappingFiles);
}
}
My test classes are looks like
#ContextConfiguration(classes = { TestApplication.class })
public class CommissionRuleServiceTest extends AbstractTestNGSpringContextTests
{
#InjectMocks
#Autowired
MyService
#Mock
MyDAO;
#BeforeMethod
public void initMock()
{
MockitoAnnotations.initMocks(this);
}
#Test(dataProvider = "....")
......
......
}
When I run project it shows hugh log on console and it takes times say 20.00secs for just few small tests.
Some of statements from log are,
DEBUG o.s.c.i.s.PathMatchingResourcePatternResolver - Searching directory
DEBUG o.s.c.a.ConfigurationClassPostProcessor
DEBUG o.s.c.a.ClassPathBeanDefinitionScanner
DEBUG o.s.c.i.s.PathMatchingResourcePatternResolver
DEBUG o.s.b.f.s.DefaultListableBeanFactory
DEBUG o.a.c.b.converters.ArrayConverter
DEBUG org.dozer.loader.xml.XMLParser
DEBUG org.hibernate.cfg.SettingsFactory
DEBUG o.h.cfg.annotations.CollectionBinder
DEBUG o.h.cfg.annotations.TableBinder
DEBUG o.h.p.w.spi.MetamodelGraphWalker - Visiting attribute path : MyEntity
DEBUG o.s.b.f.s.DefaultListableBeanFactory
DEBUG org.hibernate.SQL
Why it is taking such a "hugh" time? What should I need to do?
The investigation:
The #SpringBootApplication annotation is equivalent to the following annotations with default attributes:
#Configuration - Indicates that the class contains one or more #Bean methods. Plays together with #ComponentScan.
#EnableAutoConfiguration - Will attempt to guess and configure beans that you are likely to need. This might cause some performance penalty depending on your application.
#ComponentScan - Configures component scanning. As the package is not defined, scanning will occur from the package of the class with this annotation.
Without more code it is not possible to give you an accurate guess, but I think most of the performance penalty is caused by Spring Boot initialization.
By default the logging level is set to INFO in Spring Boot, probably you changed that?
Add this to application.properties or any other level you need (TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF)
logging.level.root=WARN
As was said before auto configuration may impact performance.
You can play with excluding some configurations that you don't need.
Here is an example (random set - don't follow blindly)
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
ErrorMvcAutoConfiguration.class, SecurityAutoConfiguration.class, SessionAutoConfiguration.class,
ValidationAutoConfiguration.class, ThymeleafAutoConfiguration.class, WebSocketAutoConfiguration.class,
DispatcherServletAutoConfiguration.class, EmbeddedServletContainerAutoConfiguration.class,
JmxAutoConfiguration.class, MultipartAutoConfiguration.class, WebMvcAutoConfiguration.class,
JacksonAutoConfiguration.class, SpringApplicationAdminJmxAutoConfiguration.class,
MessageSourceAutoConfiguration.class, SendGridAutoConfiguration.class, FreeMarkerAutoConfiguration.class,
GroovyTemplateAutoConfiguration.class, DeviceDelegatingViewResolverAutoConfiguration.class,
SitePreferenceAutoConfiguration.class, MustacheAutoConfiguration.class,
PersistenceExceptionTranslationAutoConfiguration.class})
for test classes I would recommend using
#SpringBootTest(classes = TestApplication.class)
also you can exclude Tomcat if you don't need it in your tests
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
and try to give us more details

Categories