Persistence configuration question - java

I have a web application (GWT/Vaadin based), which up to now I launched via
mvn jetty:run
Now I want to run it on another web server (also Jetty) and get database connection problems.
In the WAR file there is no persistence.xml file. Can this be the reason for the failure?
If yes, how should I configure the persistence, if
а) I'm using Java DB (Derby),
b) Hibenate and
c) now configure the DB connection like shown below
?
Thanks in advance
Dmitri
private void tryToOpenSession(final String aConnectionString)
throws Throwable {
...
state = PersistenceState.OPENING_CONNECTION;
final Configuration cnf = new Configuration();
cnf.setProperty(Environment.DRIVER,
"org.apache.derby.jdbc.EmbeddedDriver");
cnf.setProperty(Environment.URL, aConnectionString);
cnf.setProperty(Environment.DIALECT, DerbyDialect.class.getName());
cnf.setProperty(Environment.SHOW_SQL, "true");
cnf.setProperty(Environment.HBM2DDL_AUTO, "update");
cnf.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
cnf.addResource("persistence/Entity1.hbm.xml");
cnf.addResource("persistence/Entity2.hbm.xml");
...
cnf.addResource("persistence/EntityN.hbm.xml");
sessionFactory = cnf.buildSessionFactory();
session = getSession();
...
state = PersistenceState.CONNECTION_OPEN;
}
UPD: Here's the exception:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.derby.jdbc.EmbeddedDriver
at java.lang.Class.forName0(Native Method) ~[na:1.6.0_20]
at java.lang.Class.forName(Class.java:186) ~[na:1.6.0_20]
at org.hibernate.connection.DriverManagerConnectionProvider.configure(DriverManagerConnectionProvider.java:80) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:143) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:84) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.cfg.SettingsFactory.createConnectionProvider(SettingsFactory.java:459) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:91) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.cfg.Configuration.buildSettingsInternal(Configuration.java:2833) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2829) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1840) ~[hibernate-core-3.6.0.Final.jar:3.6.0.Final]

Exception clearly says that org.apache.derby.jdbc.EmbeddedDriver or some of its dependencies can't be found in the classpath. Usually you need to put required jar files into /WEB-INF/lib (or declare them in pom.xml to make Maven put them automatically).

Related

Bootstrap Hibernate SessionFactory in Netty/Armeria handler method fails with ClassNotFoundException

I have a Java Application that uses Armeria for a Web Service. When I create my Hibernate SessionFactory in the main method it works fine. But I am trying to create the SessionFactory when a certain Http Endpoint is called. In the handler method the session factory can not be created
Exception in thread "Thread-1" org.hibernate.internal.util.config.ConfigurationException: Unable to perform unmarshalling at line number 0 and column 0 in RESOURCE hibernate.cfg.xml. Message: null
Caused by: javax.xml.bind.JAXBException
- with linked exception:
[java.lang.ClassNotFoundException: com/sun/xml/bind/v2/ContextFactory]
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:226)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:441)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at org.hibernate.boot.cfgxml.internal.JaxbCfgProcessor.unmarshal(JaxbCfgProcessor.java:122)
... 17 more
Caused by: java.lang.ClassNotFoundException: com/sun/xml/bind/v2/ContextFactory
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javax.xml.bind.ContextFinder.safeLoadClass(ContextFinder.java:577)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:224)
... 21 more
All I could find about this error is that JaxB is not provided for Java > 8 but i am using Java 8 and it works fine if I just create it at Application launch.
I believe it's some sort of class path conflict. In Java 8, the following code fails with ClassNotFoundException: com/sun/xml/bind/v2/ContextFactory, as reported in the question:
public class MyService {
#Get("/start")
public HttpResponse start() throws Exception {
final StandardServiceRegistryBuilder registryBuilder =
new StandardServiceRegistryBuilder().configure();
...
}
}
However, the problem goes away after upgrading to a newer Java version, such as Java 11.
Fortunately, the problem can be worked around by specifying the context class loader explicitly:
#Get("/start")
public HttpResponse start() throws Exception {
Thread.currentThread().setContextClassLoader(MyService.class.getClassLoader());
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
final StandardServiceRegistryBuilder registryBuilder =
new StandardServiceRegistryBuilder().configure();
...
}

How to access JNDI DataSource with Play Framework

According to this documentation:
https://www.playframework.com/documentation/2.5.x/JavaDatabase#exposing-the-datasource-through-jndi
I simply need another entry in my application.conf to expose a DataSource in JNDI:
db.default.driver=org.h2.Driver
db.default.url="jdbc:h2:mem:play"
db.default.jndiName=DefaultDS
I've added "tyrex" % "tyrex" % "1.0.1" to my libraryDepenencies in build.sbt.
From reading several other posts on this, it sound like I should be able to simply use
DataSource ds = (DataSource) play.api.libs.JNDI.initialContext().lookup("DefaultDS");
To fetch the DataSource from JNDI. However, when I try this it throws the following Exception:
javax.naming.NameNotFoundException: DefaultDS not found
at tyrex.naming.MemoryContext.internalLookup(Unknown Source)
at tyrex.naming.MemoryContext.lookup(Unknown Source)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
The main reason I'm trying to do this is so that Quartz can re-use the DataSource/ConnectionPool created by Play instead of defining another in quartz.properties. According to the docs:
http://www.quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigDataSources.html
I should need the following two lines in quartz.properties:
org.quartz.jobStore.dataSource = h2
org.quartz.dataSource.h2.jndiURL = DefaultDS
However, Quartz throws a bunch of exceptions:
java.sql.SQLException: Could not retrieve datasource via JNDI url 'DefaultDS' javax.naming.NameNotFoundException: DefaultDS not found [See nested exception: java.sql.SQLException: Could not retrieve datasource via JNDI url 'DefaultDS' javax.naming.NameNotFoundException: DefaultDS not found]
I'm not sure where to go next. Any help would be appreciated.
Thanks.
Found it.
I simply needed to add jdbc to my libraryDependencies in build.sbt. This created and exposed the DataSource in JNDI.

Map Entities loaded dynamically from external jars or outside classpath

I need to map Entities that are not listed at hibernate.cfg.xml, those classes are loaded dynamically
from an arbitraty folder. I'm trying to register a ClassLoaderService to change the loading behavior, the
following code runs fine if the classes are defined at compile time and exist in the classpath, but if
I try to map a dinamically loaded class I get ClassNotFoundException. There are some questions about the same issue, but I didn't find any working solution.
URL file = ConsultaBase.class.getProtectionDomain().getCodeSource().getLocation().toURI().resolve("implementacao/").resolve("hibernate.cfg.xml").toURL();
Configuration configuration = new Configuration()
.addAnnotatedClass(Registro.class).configure(file);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder (
new BootstrapServiceRegistryImpl(
new ClassLoaderServicePirilampo(Registro.class.getClassLoader()),
new LinkedHashSet<Integrator>()
)
)
.applySettings(configuration.getProperties())
.addService(ClassLoaderService.class, new ClassLoaderServicePirilampo())
.build();
//this line throws ClassNotFoundException
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
I extended the ClassLoaderServiceImpl in order to log the requested classes, and noticed that running from JUnit, from the project where the classes are defined, it works fine, I get the class loading log from the Service. But the Service never receives
the request for the same class if I addAnnotatedClass that was loaded dinamically (from GroovyClassLoader).
The last line throws de folowing error:
17:06:49 ERROR [AssertionFailure] HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.ClassNotFoundException: implementacao.Registro
PersistentClass name cannot be converted into a Class
org.hibernate.AssertionFailure: PersistentClass name cannot be converted into a Class
at org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId(BinderHelper.java:817)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:2169)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:963)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:796)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3788)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3742)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at implementacao.ConsultaBase.createSessionFactory(ConsultaBase.java:64)
at implementacao.ConsultaBase.consultar(ConsultaBase.java:92)
at implementacao.ConsultaBase$consultar.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
at ConsultaBaseConector.run(ConsultaBaseConector.groovy:6)
at groovy.util.GroovyScriptEngine.run(GroovyScriptEngine.java:551)
at br.org.fplf.processo.maquinaexecucao.parser.ParserAtividadeAutomatica.executar(ParserAtividadeAutomatica.java:43)
at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.executarAtividadeAutomatica(MaquinaExecucao.java:1050)
at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.executarAtividadeFluxo(MaquinaExecucao.java:973)
at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.executar(MaquinaExecucao.java:646)
at br.org.fplf.processo.maquinaexecucao.MaquinaExecucao.run(MaquinaExecucao.java:368)
Caused by: java.lang.ClassNotFoundException: implementacao.Registro
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at org.hibernate.annotations.common.util.ReflectHelper.classForName(ReflectHelper.java:60)
at org.hibernate.annotations.common.reflection.java.JavaReflectionManager.classForName(JavaReflectionManager.java:138)
at org.hibernate.cfg.BinderHelper.getPropertyOverriddenByMapperOrMapsId(BinderHelper.java:813)
... 20 more
This worked for me:
Thread.currentThread().setContextClassLoader(DynamicallyLoadedClass.getClassLoader());
example:
URL file = ConsultaBase.class.getProtectionDomain().getCodeSource().getLocation()
.toURI().resolve("hibernate.cfg.xml").toURL();
Configuration configuration = new Configuration()
.addAnnotatedClass(Registro.class).configure(file);
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.build();
Thread.currentThread().setContextClassLoader(Registro.class.getClassLoader());
sessionFactory = configuration.buildSessionFactory(serviceRegistry);

Getting exception while refreshing Spring ApplicationContext in Spring Boot application

We are using Spring Boot for our application.
After starting the application, in the runtime we are adding(loading) a new Bean to the existing Applicationcontext.
AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
appContext.register(NewBean.class);
appContext.refresh();
after adding the bean we are doing a refresh of applicationContext
During the refresh the MBean is trying to reregister some endpoints and we are getting the following error
(getting error for all these endpoints - requestMappingEndpoint, environmentEndpoint, healthEndpoint, beansEndpoint, infoEndpoint, metricsEndpoint, traceEndpoint, dumpEndpoint,
autoConfigurationAuditEndpoint, shutdownEndpoint, configurationPropertiesReportEndpoint)
Caused by: javax.management.InstanceAlreadyExistsException: org.springframework.boot:type=Endpoint,name=configurationPropertiesReportEndpoint
at com.sun.jmx.mbeanserver.Repository.addMBean(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerWithRepository(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(Unknown Source)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(Unknown Source)
at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(Unknown Source)
at org.springframework.jmx.support.MBeanRegistrationSupport.doRegister(MBeanRegistrationSupport.java:195)
at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:662)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:605)
Can anyone please tell how to skip this exception?
I have tried the following too
#EnableIntegrationMBeanExport(registration = RegistrationPolicy.REPLACE_EXISTING)
but getting the below exception
Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.integration.monitor.IntegrationMBeanExporter#16c5464] with key 'integrationMbeanExporter'; nested exception is javax.management.InstanceAlreadyExistsException: org.springframework.integration.monitor:name=integrationMbeanExporter,type=IntegrationMBeanExporter
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:609)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:534)
at org.springframework.jmx.export.MBeanExporter.afterPropertiesSet(MBeanExporter.java:416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 22 more
Caused by: javax.management.InstanceAlreadyExistsException: org.springframework.integration.monitor:name=integrationMbeanExporter,type=IntegrationMBeanExporter
at com.sun.jmx.mbeanserver.Repository.addMBean(Repository.java:437)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerWithRepository(DefaultMBeanServerInterceptor.java:1898)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerDynamicMBean(DefaultMBeanServerInterceptor.java:966)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerObject(DefaultMBeanServerInterceptor.java:900)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.registerMBean(DefaultMBeanServerInterceptor.java:324)
at com.sun.jmx.mbeanserver.JmxMBeanServer.registerMBean(JmxMBeanServer.java:522)
at org.springframework.jmx.support.MBeanRegistrationSupport.doRegister(MBeanRegistrationSupport.java:195)
at org.springframework.jmx.export.MBeanExporter.registerBeanInstance(MBeanExporter.java:662)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:599)
... 26 more
Before you call refresh on an existing ApplicationContext, you should first destroy it else beans keep running.
AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext();
appContext.register(NewBean.class);
appContext.refresh();
What you show here is that you are constructing a new context instead of reusing an existing one. The register method is also intended for #Configuration classes not arbitrary beans. If you want to add those just use one of the methods on the ApplicationContext like, registerSingleton. But in general adding beans at runtime should be a bad thing (imho).
Some applicationContext can refresh times, but not AnnotationConfigApplicationContext.
when you construct AnnotationConfigApplicationContext, which had run the refresh method, so it will be reported exception, you can destroy it first, and then refresh

Java using hibernate

i was trying a basic program in java using hibernate... but im getting the following error description
WARN: HHH000277: Could not bind factory to JNDI
org.hibernate.service.jndi.JndiException: Error parsing JNDI name [hiber]
at org.hibernate.service.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:92)
at org.hibernate.service.jndi.internal.JndiServiceImpl.bind(JndiServiceImpl.java:108)
at org.hibernate.internal.SessionFactoryRegistry.addSessionFactory(SessionFactoryRegistry.java:89)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:480)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1769)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1840)
at manageEmployee.main(manageEmployee.java:26)
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getURLOrDefaultInitCtx(Unknown Source)
at javax.naming.InitialContext.getNameParser(Unknown Source)
at org.hibernate.service.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:86)
... 6 more
Exception in thread "main" java.lang.ClassCastException: org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction cannot be cast to javax.transaction.Transaction
at manageEmployee.addEmployee(manageEmployee.java:44)
at manageEmployee.main(manageEmployee.java:34)
I fixed this by removing the name attribute from opening session factory tag in my hibernate configuration file so that it looks like the following:
<session-factory>
instead of
<session-factory name="">
Check your imports statement if found this:
import javax.transaction.Transaction;
Then replace this with:
import org.hibernate.Transaction;
And remove casting from all places find where you're casting like below:
tx = (Transaction) session.beginTransaction();
Remove
(Transaction)
to remove casting from all places.
This could be triggert by either there are some depending libarys of hibernate missing or u have imported some false libarys with the same name.

Categories