Launching Spring Boot's jar file throws me these errors:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'temperatureController' defined in URL <...>
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'temperatureService' defined in URL <...>
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.example.temperaturetracker.services.TokenService]: Constructor threw exception; nested exception is java.lang.IllegalStateException: FirebaseApp with name [DEFAULT] doesn't exist.
Each class contains appropriate #: #Service or #RestController or #SpringBootApplication or #Entity or #Repository.
Some classes:
#Service
public class TemperatureService {
private final AlertService alertService;
#Autowired
public TemperatureService(AlertService alertService) {
this.alertService = alertService;
}
<...>
}
#Service
class AlertService #Autowired constructor(private val tokenService: TokenService,
private val cloudMessagingService: CloudMessagingService) {
#PostConstruct
fun initialize() {
<...>
}
}
#Service
public class CloudMessagingService {
final Logger logger = LoggerFactory.getLogger(CloudMessagingService.class);
public void sendFirebaseMessage() {
<...>
try {
var response = FirebaseMessaging.getInstance().send(fbMessage);
logger.debug("Notification response: " + response);
} catch (FirebaseMessagingException e) {
e.printStackTrace();
logger.error("Error sending Firebase Cloud Message: " + e);
}
}
}
#Service
public class FirebaseInitialize {
#PostConstruct
public void initialize() {
try {
FileInputStream serviceAccount =
new FileInputStream("hidden-path");
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("hidden-path")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
e.printStackTrace();
}
}
}
#SpringBootApplication
public class TemperatureTrackerApplication {
public static void main(String[] args) {
SpringApplication.run(TemperatureTrackerApplication.class, args);
}
}
These errors occurs only when I launch my jar file. Running app via green arrow or Shift + F10 everything works perfectly.
Make sure your Firebase configuration is ok because the error is thrown when SpringBoot try to execute the class
FirebaseInitialize
I've changed my class's FirebaseInitialize method initialize() to:
try {
ClassPathResource serviceAccount =
new ClassPathResource("myFile.json"); // it is in resources folder
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount.getInputStream()))
.setDatabaseUrl("database-path-provided-by-firebase.app")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
e.printStackTrace();
}
FileInputStream I've used before expected the resource to be on the file system, which cannot be nested in a jar file. Thus, using getInputStream() of ClassPathResource worked.
Please read more: Classpath resource not found when running as jar
Use a #PostConstruct method to initialize Firebase inside your #SpringBootApplication class. So the case above should become
#SpringBootApplication
public class TemperatureTrackerApplication {
public static void main(String[] args) {
SpringApplication.run(TemperatureTrackerApplication.class, args);
}
#PostConstruct
public void initialize() {
try {
FileInputStream serviceAccount =
new FileInputStream("hidden-path");
FirebaseOptions options = FirebaseOptions.builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount))
.setDatabaseUrl("hidden-path")
.build();
FirebaseApp.initializeApp(options);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Related
I have created application using apache karaf and I need to connect Datasource using jndi but it is not working giving below error:
Caused by: javax.naming.NameNotFoundException: env is not bound; remaining name 'env/jdbc/classicmodels'
at org.eclipse.jetty.jndi.NamingContext.getContext(NamingContext.java:241)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:491)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:491)
at org.eclipse.jetty.jndi.NamingContext.lookup(NamingContext.java:505)
at org.eclipse.jetty.jndi.java.javaRootURLContext.lookup(javaRootURLContext.java:101)
at java.naming/javax.naming.InitialContext.lookup(InitialContext.java:409)
at org.springframework.jndi.JndiTemplate.lambda$lookup$0(JndiTemplate.java:157)
at org.springframework.jndi.JndiTemplate.execute(JndiTemplate.java:92)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:157)
at org.springframework.jndi.JndiTemplate.lookup(JndiTemplate.java:179)
at org.springframework.jndi.JndiLocatorSupport.lookup(JndiLocatorSupport.java:96)
at org.springframework.jndi.JndiObjectLocator.lookup(JndiObjectLocator.java:114)
at org.springframework.jndi.JndiObjectFactoryBean.lookupWithFallback(JndiObjectFactoryBean.java:239)
at org.springframework.jndi.JndiObjectFactoryBean.afterPropertiesSet(JndiObjectFactoryBean.java:225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
And for this in Activator I am writing below code to configure jndi:
#SpringBootConfiguration
#EnableAutoConfiguration
#Import(ControllerConfig.class)
public class Activator implements BundleActivator {
// Bundle start stop code.
}
Now ControllerConfig code is as below:
#Configuration
#ServletComponentScan(basePackages = "com")
public class ControllerConfig extends SpringBootServletInitializer {
#Bean
public ConfigurableServletWebServerFactory webServerFactory() {
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.addServerCustomizers(server -> {
org.eclipse.jetty.webapp.Configuration.ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
classlist.addAfter("org.eclipse.jetty.webapp.FragmentConfiguration", "org.eclipse.jetty.plus.webapp.EnvConfiguration", "org.eclipse.jetty.plus.webapp.PlusConfiguration");
classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration", "org.eclipse.jetty.annotations.AnnotationConfiguration");
BasicDataSource simpleDataSource = new BasicDataSource();
simpleDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
simpleDataSource.setUsername("root");
simpleDataSource.setPassword("root");
simpleDataSource.setUrl("jdbc:mysql://localhost:3306/classicmodels");
String jndiName = "jdbc/classicmodels";
try {
Resource resource = new Resource(server, jndiName, simpleDataSource);
///server.setAttribute("java:comp/env/" + jndiName, resource);
server.join();
} catch (Exception e) {
e.printStackTrace();
}
});
return factory;
}
}
If someone can help please let me know how to do it or what I am doing.
May it help someone just below changes are required and it will work:
try {
Context icontext = new InitialContext();
Context compCtx = (Context) icontext.lookup("java:comp");
compCtx.createSubcontext("env");
new Resource("java:comp/env/" + jndiName, simpleDataSource);
server.join();
} catch (Exception e) {
e.printStackTrace();
}
I am facing some difficulties in writing junit test to pass the for loop condition to getParts() method from SlingHttpServletRequest.getParts(). There is no problem with the implementation, I am able to process the file attachment properly. However, I am unable to do so in the junit test.
The following is my implementation:
#Model(adaptables = SlingHttpServletRequest.class)
public class Comment {
//Variables declaration
#Inject
private CommentService service;
#PostConstruct
public void setup() {
requestData = new JSONObject();
for (String item : request.getRequestParameterMap().keySet()) {
try {
requestData.put(item, request.getParameter(item));
}
} catch (Exception e) {
Throw error message
}
}
//Upload attachment to server
try {
for (Part part : request.getParts()) { <= The JUnit test stopped at this line and throw the error below
} catch (Exception e) {
Throw error message
}
I have tried using a SlingHttpServletRequestWrapper class to override the getParts method but to no avail.
The following is my junit test:
public class CommentTest {
public final AemContext context = new AemContext();
private CommentService commentService = mock(CommentService.class);
#InjectMocks
private Comment comment;
private static String PATH = "/content/testproject/en/page/sub-page";
#Before
public void setUp() throws Exception {
context.addModelsForPackage("de.com.adsl.sightly.model");
context.load().json("/components/textrte.json", PATH);
context.currentPage(PATH);
}
#Test
public void testSetup() throws IOException, ServletException {
//before
context.request().setParameterMap(getRequestCat1());
context.registerService(CommentService.class, commentService);
Resource resource = context.resourceResolver().getResource(PATH + "/jcr:content/root/responsivegrid/textrte");
assertNotNull(resource);
//when
comment = new CustomRequest(context.request()).adaptTo(Comment.class);
//then
comment.setup();
}
private class CustomRequest extends SlingHttpServletRequestWrapper {
public CustomRequest(SlingHttpServletRequest request) {
super(request);
}
#Override
public Collection<Part> getParts() {
final String mockContent =
"------WebKitFormBoundarycTqA2AimXQHBAJbZ\n" +
"Content-Disposition: form-data; name=\"key\"\n" +
"\n" +
"myvalue1\n" +
"------WebKitFormBoundarycTqA2AimXQHBAJbZ";
final List<Part> parts = MockPart.parseAll(mockContent);
assertNotNull(parts);
return parts;
}
};
}
The following is the error message that I encountered:
14:53:04.918 [main] ERROR de.com.adsl.sightly.model.Comment - Error Message: null
java.lang.UnsupportedOperationException: null
at org.apache.sling.servlethelpers.MockSlingHttpServletRequest.getParts(MockSlingHttpServletRequest.java:882) ~[org.apache.sling.servlet-helpers-1.1.10.jar:?]
at de.com.adsl.sightly.model.Comment.uploadFile(Feedback.java:137) ~[classes/:?]
at de.com.adsl.sightly.model.Comment.setup(Feedback.java:82) [classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_201]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_201]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_201]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_201]
at org.apache.sling.models.impl.ModelAdapterFactory.invokePostConstruct(ModelAdapterFactory.java:792) [org.apache.sling.models.impl-1.3.8.jar:?]
at org.apache.sling.models.impl.ModelAdapterFactory.createObject(ModelAdapterFactory.java:607) [org.apache.sling.models.impl-1.3.8.jar:?]
at org.apache.sling.models.impl.ModelAdapterFactory.internalCreateModel(ModelAdapterFactory.java:335) [org.apache.sling.models.impl-1.3.8.jar:?]
at org.apache.sling.models.impl.ModelAdapterFactory.getAdapter(ModelAdapterFactory.java:211) [org.apache.sling.models.impl-1.3.8.jar:?]
...
I have looked up various solutions online such as writing two mockito when statements but has not been successful. I would greatly appreciate any form of help or sharing of knowledge if you have encountered the following issue previously. Thank you!
From the source code of MockSlingServletResquest it always throws that exception as it's not supported yet by the mocked class.
https://github.com/apache/sling-org-apache-sling-servlet-helpers/blob/71ef769e5564cf78e49d6679a3270ba8706ae406/src/main/java/org/apache/sling/servlethelpers/MockSlingHttpServletRequest.java#L953
Maybe you should consider writing a servlet, or another approach.
Here is my FileStorageProperties class:
#Data
#ConfigurationProperties(prefix = "file")
public class FileStorageProperties {
private String uploadDir;
}
This gives me saying : not registered via #enableconfigurationproperties or marked as spring component.
And here is my FileStorageService :
#Service
public class FileStorageService {
private final Path fileStorageLocation;
#Autowired
public FileStorageService(FileStorageProperties fileStorageProperties) {
this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
.toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public String storeFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
// Check if the file's name contains invalid characters
if(fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
// Copy file to the target location (Replacing existing file with the same name)
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
public Resource loadFileAsResource(String fileName) {
try {
Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
Resource resource = new UrlResource(filePath.toUri());
if(resource.exists()) {
return resource;
} else {
throw new MyFileNotFoundException("File not found " + fileName);
}
} catch (MalformedURLException ex) {
throw new MyFileNotFoundException("File not found " + fileName, ex);
}
}
}
This gives me error saying : could not autowire no beans of type found.
And here is my project structure :
And when I try to run it, it gives me :
APPLICATION FAILED TO START
Description:
Parameter 0 of constructor in com.mua.cse616.Service.FileStorageService required a bean of type 'com.mua.cse616.Property.FileStorageProperties' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.mua.cse616.Property.FileStorageProperties' in your configuration.
How can I resolve this?
This is expected as #ConfigurationProperties does not make a class a Spring Component. Mark the class with #Component and it should work. Note that a class can only be injected if it is a Component.
Edit: From Spring 2.2+ (Reference)
#ConfigurationProperties scanning
Classes annotated with #ConfigurationProperties can now be found via classpath scanning as an alternative to using #EnableConfigurationProperties or #Component. Add #ConfigurationPropertiesScan to your application to enable scanning.
Try to annotate with #ConfigurationProperties and #Component
In here , Spring Boot #ConfigurationProperties is annotation for externalized configuration.if you are trying to inject property value from a property file to a class, you can add #ConfigurationProperties at a class level with stereotype annotations such as #Component or add #ConfigurationProperties to a #Bean method.
add bellow annotation in FileStorageProperties class:
#Component
I have written a program to read messages from a Solace queue. I am getting the below error.
Can you please help?
Code given below:
My main config is given below:
public class ReadFromQueueConfig {
#Autowired
private PrintMessageFromQueue printMessageFromQueue;
String queueName = "MY.SAMPLE.SOLACE.QUEUE";
#Bean
public CachingConnectionFactory jmsConnectionFactory() {
CachingConnectionFactory ccf = new CachingConnectionFactory();
try {
SolConnectionFactory scf = SolJmsUtility.createConnectionFactory();
scf.setHost("host");
scf.setUsername("username");
scf.setVPN("vpm");
scf.setPassword("password");
scf.setDirectTransport(false);
ccf.setTargetConnectionFactory(scf);
} catch (Exception e) {
logger.debug(e.getMessage());
}
return ccf;
}
#Bean
public IntegrationFlow handleJsmInput() {
return IntegrationFlows
.from(Jms.inboundAdapter(jmsConnectionFactory()).destination(queueName))
.handle(printMessageFromQueue)
.get();
}
}
PrintMessageFromQueue.java:
UPDATE:
My main class:
#SpringBootApplication
#EnableIntegration
#IntegrationComponentScan
public class TestReadFromQueueApplication {
public static void main(String[] args) {
SpringApplication.run(TestReadFromQueueApplication.class, args);
}
}
You can do something like this in the main() after creating an ApplicationContext:
final Scanner scanner = new Scanner(System.in);
context.close();
So, you application is not going to exit until some input from the console.
Also you can wait for the messages to be consumed, e.g. via the QueueChannel.receive().
Some sample to block a main in done in the Apache Kafka sample in the Spring Integration Samples: https://github.com/spring-projects/spring-integration-samples/blob/master/basic/kafka/src/main/java/org/springframework/integration/samples/kafka/Application.java
Module Class
public class MorphiaModule extends AbstractModule {
#Override
protected void configure() {
bind(PlayMorphia.class).asEagerSingleton();
}
}
PlayMorphia
#Singleton
public class PlayMorphia {
MongoClient mongo = null;
Datastore datastore = null;
Morphia morphia = null;
#Inject
public PlayMorphia(ApplicationLifecycle lifecycle, Environment env, Configuration config) {
try {
configure(config, env.classLoader(), env.isTest()); // Method calling to get the config
} catch (Exception e) {
e.printStackTrace();
}
lifecycle.addStopHook(()->{
if (env.isTest()) {
mongo().close();
}
return CompletableFuture.completedFuture(null);
});
}
}
In My application.conf, I mentioned the correct package/path name for Module class i.e.
play.modules.enabled += "configuration.MorphiaModule"
I followed the Play framework official doc on Eager Binding: https://www.playframework.com/documentation/2.6.x/JavaDependencyInjection#Eager-bindings
At compile time, I am getting this:
CreationException: Unable to create injector, see the following errors:
1) No implementation for play.inject.ApplicationLifecycle was bound.
while locating play.inject.ApplicationLifecycle
for the 1st parameter of configuration.PlayMorphia. .
(PlayMorphia.java:28)
at configuration.MorphiaModule.configure(MorphiaModule.java:24) (via
modules: com.google.inject.util.Modules$OverrideModule ->
configuration.MorphiaModule)
What am I doing wrong here? Any help would be appreciable.