I am working on a project where in one class I need to load json
file src/main/resources
.
src/
main/java/FirebaseTokenVerifier
main/resources/staging_firebase.json
The class ForebaseTokenVerifier
loads this JSON
file in constructor as
@Component
public class FirebaseTokenVerifier implements TokenVerifier {
private FirebaseAuth firebaseAuth;
// TODO (hhimanshu): resourceFile and DatabaseURL are hardcoded, this should be picked by external file
// or should be picked up conditionally based on environment
public FirebaseTokenVerifier() throws IOException, URISyntaxException {
final String resourceName = "staging_firebase.json";
System.out.println("Getting Resource: " + resourceName);
Path path = Paths.get(ClassLoader.getSystemClassLoader().getResource(resourceName).toURI());
FileInputStream serviceAccount = new FileInputStream(path.toFile());
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(serviceAccount))
.setDatabaseUrl("https://staging-myapp.firebaseio.com")
.build();
FirebaseApp defaultApp = FirebaseApp.initializeApp(options);
firebaseAuth = FirebaseAuth.getInstance(defaultApp);
}
/// more things here .....
}
When I run mvn spring-boot:run
, I see that the json
file is loaded correctly as
2017-07-26 15:57:33.611 INFO 49104 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-07-26 15:57:33.611 INFO 49104 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1424 ms
Getting Resource: staging_firebase.json
2017-07-26 15:57:33.799 INFO 49104 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
and everything works fine. I then, try to do the following
mvn clean package; java -jar target/myapp-core-0.0.1-SNAPSHOT.jar
But this fails on runtime
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 35 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'firebaseTokenVerifier' defined in URL [jar:file:/Users/Harit.Himanshu/bl/sources/idea/myapp-core/targ
et/myapp-core-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/myapp/api/auth/FirebaseTokenVerifier.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationEx
ception: Failed to instantiate [com.myapp.api.auth.FirebaseTokenVerifier]: Constructor threw exception; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 49 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.myapp.api.auth.FirebaseTokenVerifier]: Constructor threw exception; nested exception is java.lang.NullPointe
rException
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 61 common frames omitted
Caused by: java.lang.NullPointerException: null
at com.myapp.api.auth.FirebaseTokenVerifier.<init>(FirebaseTokenVerifier.java:31) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_131]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_131]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 63 common frames omitted
It fails on L31
which is
Path path = Paths.get(ClassLoader.getSystemClassLoader().getResource(resourceName).toURI());
I also confirm that the json
file is present in the jar file as
✗ jar -tvf target/myapp-core-0.0.1-SNAPSHOT.jar| grep json
2355 Wed Jul 26 16:00:44 NZST 2017 BOOT-INF/classes/staging_firebase.json
64952 Tue Jan 07 19:29:24 NZDT 2014 BOOT-INF/lib/json-20140107.jar
What is going wrong here? and how come Spring-Boot
is able to resolve this path correctly?
UPDATE
After looking at https://stackoverflow.com/a/36372773/379235, I changed my code to look like
FileInputStream serviceAccount = new FileInputStream(new ClassPathResource(resourceName).getFile());
and it fails now saying
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'firebaseTokenVerifier' defined in URL [jar:file:/Users/Harit.Himanshu/bl/sources/idea/myapp-core/target/myapp-core-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/myapp/api/auth/FirebaseTokenVerifier.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationEx
ception: Failed to instantiate [com.myapp.api.auth.FirebaseTokenVerifier]: Constructor threw exception; nested exception is java.io.FileNotFoundException: class path resource [staging_firebase.json] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/Users/Harit.Himanshu/bl/sources/idea/myapp-core/target/myapp-core-0.0.1-SNAPSHOT.jar!/BOO
T-INF/classes!/staging_firebase.json
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 49 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.myapp.api.auth.FirebaseTokenVerifier]: Constructor threw exception; nested exception is java.io.FileNotFoundException: class path resource [staging_firebase.json] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/Users/Harit.Himanshu/bl/sources/idea/penn
ytrak-core/target/myapp-core-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/staging_firebase.json
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 61 common frames omitted
Caused by: java.io.FileNotFoundException: class path resource [staging_firebase.json] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/Users/Harit.Himanshu/bl/sources/idea/myapp-core/target/myapp-core-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/staging_firebase.json
at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:215) ~[spring-core-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:52) ~[spring-core-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
at com.myapp.api.auth.FirebaseTokenVerifier.<init>(FirebaseTokenVerifier.java:34) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_131]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_131]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_131]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_131]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142) ~[spring-beans-4.3.8.RELEASE.jar!/:4.3.8.RELEASE]
... 63 common frames omitted
Even though I can see that in the jar file
✗ jar -tvf target/myapp-core-0.0.1-SNAPSHOT.jar| grep json
2355 Wed Jul 26 16:54:02 NZST 2017 BOOT-INF/classes/staging_firebase.json
64952 Tue Jan 07 19:29:24 NZDT 2014 BOOT-INF/lib/json-20140107.jar
cannot be resolved to absolute file path because it does not reside in the file system
This is pretty explicit. You're trying to access it as file, when it is NOT a file but a resource embedded in the JAR.
Research ClassLoader#getResourceAsStream()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With