Skip to content

DefaultPersistenceUnitManager.determineDefaultPersistenceUnitRootUrl fails when run from a shaded jar [SPR-14246] #18819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue May 4, 2016 · 9 comments
Assignees
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented May 4, 2016

Andy Wilkinson opened SPR-14246 and commented

I'll open a PR with a sample that reproduces the problem. It boils down to a call to ClassLoader.getResource("") returning null when there are only jars on the classpath.

The failure is:

May 04, 2016 4:49:33 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@49c2faae: startup date [Wed May 04 16:49:33 BST 2016]; root of context hierarchy
May 04, 2016 4:49:33 PM org.springframework.context.annotation.AnnotationConfigApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManager' defined in com.example.ShadedClasspathRootApplication: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: Unable to resolve persistence unit root URL
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManager' defined in com.example.ShadedClasspathRootApplication: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: Unable to resolve persistence unit root URL
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:851)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
	at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
	at com.example.ShadedClasspathRootApplication.main(ShadedClasspathRootApplication.java:21)
Caused by: javax.persistence.PersistenceException: Unable to resolve persistence unit root URL
	at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.determineDefaultPersistenceUnitRootUrl(DefaultPersistenceUnitManager.java:591)
	at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.preparePersistenceUnitInfos(DefaultPersistenceUnitManager.java:443)
	at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.afterPropertiesSet(DefaultPersistenceUnitManager.java:424)
	at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:310)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
	at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
	... 11 more
Caused by: java.io.FileNotFoundException: class path resource [] cannot be resolved to URL because it does not exist
	at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:187)
	at org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager.determineDefaultPersistenceUnitRootUrl(DefaultPersistenceUnitManager.java:588)
	... 18 more

This also affects an executable jar built by Spring Boot. We used to have a hack in Boot's custom class loader that worked around this issue, but that doesn't help people who are using shaded jars, and we would prefer not to have to reintroduce the hack.


Affects: 4.3 RC1

Reference URL: spring-projects/spring-boot#5842

Issue Links:

Referenced from: commits abfe3f2

1 votes, 7 watchers

@spring-projects-issues
Copy link
Collaborator Author

Andy Wilkinson commented

Reproduction: spring-attic/spring-framework-issues#127

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Hmm, so what should we be using instead if there is no such root URL? After all, we have to provide a non-null root URL to the JPA persistence provider...

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 4, 2016

Andy Wilkinson commented

Could this be a regression of the fix for #13474?

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 4, 2016

Juergen Hoeller commented

The jar URL handling code from #13474 is still present in buildDefaultPersistenceUnitInfo... If it doesn't work in the above scenario, it is probably not a regression but rather never actually worked there.

@spring-projects-issues
Copy link
Collaborator Author

Andy Wilkinson commented

I just came to the same conclusion. I think the difference here is that there are no entities being scanned so we never go into the matchesFilter(reader, readerFactory if block and set the persistence unit root url.

@spring-projects-issues
Copy link
Collaborator Author

Andy Wilkinson commented

In this particular case the user is providing an orm.xml file. I'm not hugely familiar with the ordering of things while JPA is being initialized, but could the URL of the jar that contains that file be used as the root URL?

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Good idea...

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

We can resolve the persistence unit root from the orm.xml location now, if not set before. Please give it a try with a shaded jar...

@spring-projects-issues
Copy link
Collaborator Author

Andy Wilkinson commented

Looks good, Juergen. Thanks for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants