First of all, I tried this with Liferay CE portal-7.1.0-GA1 and Liferay portal 7.0 CE GA1. I will explain details of my process. My portal-ext.properties (Liferay HOME folder) looks:
jdbc.ext.driverClassName=oracle.jdbc.OracleDriver
jdbc.ext.url=jdbc:oracle:thin:#localhost:1521:db
jdbc.ext.username=xxx
jdbc.ext.password=xxx
JARs:
- ojdbc14.jar (\liferay-portal-7.0-ce-ga1\tomcat-8.0.32\lib)
- liferay-portal-oracledb-support-1.0 and liferay-portal-oracledb-support-1.0-SNAPSHOT (liferay-portal-7.0-ce-ga1\tomcat-8.0.32\webapps\ROOT\WEB-INF\lib)
- added ext-spring.xml (\modules\DemoService\DemoService-service\build\resources\main\META-INF\spring)
Code for ext-spring.xml
<?xml version="1.0"?>
<beans default-destroy-method="destroy" default-init-method="afterPropertiesSet" xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean"
id="liferayDataSourceFactory">
<property name="propertyPrefix" value="jdbc.ext." />
<property name="properties">
<props>
<prop key="custom.jndi.name">extDataSource</prop>
</props>
</property>
</bean-->
<bean class="com.liferay.portal.dao.jdbc.spring.DataSourceFactoryBean"
id="liferayDataSourceFactory">
<property name="propertyPrefix" value="jdbc.ext." />
</bean>
<bean
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
id="liferayDataSource">
<property name="targetDataSource" ref="liferayDataSourceFactory" />
</bean>
<alias alias="extDataSource" name="liferayDataSource" />
</beans>
Getting this ERROR:
00:10:31,259 ERROR [http-nio-8080-exec-5][render_portlet_jsp:131] null
java.lang.NullPointerException
at com.service.service.CountryLocalServiceUtil.getCountriesCount(CountryLocalServiceUtil.java:207)
at com.demo.portlet.DemoPortlet.doView(DemoPortlet.java:39)
at com.liferay.portal.kernel.portlet.LiferayPortlet.doDispatch(LiferayPortlet.java:302)
at com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet.doDispatch(MVCPortlet.java:474)
at javax.portlet.GenericPortlet.render(GenericPortlet.java:262)
at com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet.render(MVCPortlet.java:294)
at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:103)
at com.liferay.portlet.ScriptDataPortletFilter.doFilter(ScriptDataPortletFilter.java:57)
at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:100)
at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:64)
at com.liferay.portal.kernel.servlet.PortletServlet.service(PortletServlet.java:105)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at com.liferay.portal.osgi.web.servlet.context.helper.internal.ServletContextHelperRegistrationImpl$PortletServletWrapper.service(ServletContextHelperRegistrationImpl.java:507)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration.service(EndpointRegistration.java:153)
at org.eclipse.equinox.http.servlet.internal.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:50)
at com.liferay.portal.osgi.web.servlet.context.helper.internal.ServletContextHelperRegistrationImpl$RestrictPortletServletRequestFilter.doFilter(ServletContextHelperRegistrationImpl.java:527)
at org.eclipse.equinox.http.servlet.internal.registration.FilterRegistration.doFilter(FilterRegistration.java:121)
at org.eclipse.equinox.http.servlet.internal.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:45)
at org.eclipse.equinox.http.servlet.internal.servlet.ResponseStateHandler.processRequest(ResponseStateHandler.java:71)
Country is entity in service.xml, after Gradle building service, CountryLocalServiceUtil is generated. If you are using Liferay 7, this is simple process of creating first app.
This is generated class, I can give the code:
From Portlet, I just called function CountryLocalServiceUtil.getCountriesCount()
this function in CountryLocalServiceUtil is:
public static int getCountriesCount() {
return getService().getCountriesCount();
}
Open declaration is:
CountryLocalService.java #Transactional(propagation = Propagation.SUPPORTS,
readOnly = true)
public int getCountriesCount();
You're running Liferay 7.x CE. Note that Liferay Community Edition (CE) does only support Open Source databases, e.g. no Oracle. There's a community provided add-on that adds support for Oracle and other commercial databases, but you don't indicate that you've installed it.
Thus, it seems that you're running Liferay from a supported database, and try to connect to Oracle in your "jdbc.ext" database. I'd expect this to not work, as it would require the servicebuilder mapping to Oracle, though they're not contained in CE.
You can always go with pure JDBC (e.g. no service builder), or try Antonio's plugin. Currently I'm only aware that it's out for 7.0, not for 7.1 (but I might be wrong here)
I am almost sure your problem is not the database but the service object not being available as your issue is no due getCountriesCount() but on getService().
As an experiment, try not using the *Util class but an OSGi #Reference for the service you want, this should rule out the database as an issue (at least for this matter). if you cannot get the service, you will probably find better troubleshooting information than a NPE being thrown in the *Util class.
As an example, in your component:
#Reference
private volatile CountryLocalService countryLocalService;
There are examples all over Liferay's source, like:
https://github.com/liferay/liferay-portal/blob/180d89ccaa80b86e68402c73a1483cd9e1817311/modules/apps/export-import/export-import-resources-importer/src/main/java/com/liferay/exportimport/resources/importer/internal/util/ImporterFactory.java
Related
i want to deploy my application in AWS.
i have setup my env.
and in root-context.xml of my application i have setup data source.
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#mydbinstance.cnn31xputfwg.ap-northeast-2.rds.amazonaws.com:1521:orcl" />
<property name="username" value="myid" />
<property name="password" value="mypassword" />
</bean>
this setting works fine locally in tomcat server.
but in AWS, it throws this error message
nested exception is org.apache.ibatis.exceptions.PersistenceException:
Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is
java.sql.SQLException: Cannot load JDBC driver class 'oracle.jdbc.driver.OracleDriver'
The error may exist in file [/var/lib/tomcat8/webapps/ROOT/WEB-INF/classes/mappers/emp/emp-mapper.xml]
The error may involve EmpDAO.List ### The error occurred while executing a query
Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection; nested exception is
java.sql.SQLException: Cannot load JDBC driver class 'oracle.jdbc.driver.OracleDriver'
Now my question is: what should i do to use get jdbc connection in AWS?
Looks like when you run the app on AWS it lacks Oracle JDBC driver in its CLASSPATH. So the answer is to add the driver to the classpath.
And I foresee the next question: "how to do this?", and simplest way is just to copy the driver to your classpath manually.
If you don't like manual work, you can generate Spring application template using Spring Initializr. Its build script has org.springframework.boot plugin, which does two important things:
builds single jar file which includes Tomcat, so the application can be started just by java -jar my-app.jar (avoiding deployment to tomcat)
includes all dependencies from build-script dependencies section to this jar file (including Oracle JDBC driver)
I want to use my system environment variables (i.e use variable FOO that I have defined in my .bash_profile export FOO=BAR) for values in Spring's applicationContext.xml;
For example:
<bean id="dataSource" ...>
<property name="jdbcUrl" value="${FOO}" />
...
</bean>
I use both the Maven-tomcat-plugin and Tomcat inside IntelliJ to run my server.
Right now when my webapp starts up, it can't find the system variables.
What do I have to do to get Spring to read from my system environment variables?
P.S. I have already checked out how to read System environment variable in Spring applicationContext, but doesn't seem to work for me
System environment variables are different to the JVM system properties - which the spring PropertyPlaceholderConfigurer gives you access to. So you'd need to add to the JVM command:
java ... -DFOO=${FOO}
(where -DFOO is defining "FOO" as a JVM system property and ${FOO} is inserting the "BAR" value from your "FOO" environment variable)
See also the ServletContextPropertyPlaceholderConfigurer - with the SYSTEM_PROPERTIES_MODE_OVERRIDE property and a few other options.
try this (Spring Expression Language)
<bean id="dataSource" ...>
<property name="jdbcUrl" value="#{systemEnvironment.FOO}" />
...
</bean>
or add this line
<context:property-placeholder/>
to application context
Trying to deploy application ear file with following settings in JBoss-4.2.3.GA
jboss-app.xml
<jboss-app>
<loader-repository>
com.xxxx.xxx:loader=<ear-name>
<loader-repository-config>
java2ParentDelegation=false
</loader-repository-config>
</loader-repository>
</jboss-app>
persistence.xml (just a snippet)
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.format_sql" value="false"/>
<property name="jboss.entity.manager.factory.jndi.name" value="java:/XXXXFactory"/>
Got following logger info during deployment, I am not sure why an exception is listed in an INFO logger, can I not bother about this?
16:30:07,239 INFO [STDOUT] 16:30:07,238 INFO [SettingsFactory] JDBC driver: Oracle JDBC driver, version: 11.2.0.3.0
javax.ejb.EJBException: org.hibernate.HibernateException: unknown Oracle major version [11]
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:63)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
Caused by: org.hibernate.HibernateException: unknown Oracle major version [11]
at org.hibernate.dialect.DialectFactory$1.getDialectClass(DialectFactory.java:135)
at org.hibernate.dialect.DialectFactory.determineDialect(DialectFactory.java:65)
at org.hibernate.dialect.DialectFactory.buildDialect(DialectFactory.java:39)
at org.hibernate.cfg.SettingsFactory.determineDialect(SettingsFactory.java:426)
Note: We are using JBoss-Seam-2.2.0.GA
Tried: this, this and that
Please let me know if any additional information is required, I am trying to pull back the libs available in jboss to the ear.
Update: Tries
Figured out that the application is using 2 different sessions and
there is one hibernate.cfg.xml also for another legacy code, there
is no dialect specified in it.
So added Oracle10g dialect to
cfg.xml, it stopped throwing above mentioned unknown oracle
version error, but it exceptioned as it couldn't load the
10gDialect.
Beauty is both the sessions are pointing to the same datasource.
Try to add
hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
also to JBoss/server/default/deploy/ejb3.deployer/META-INF/persistence.properties.
It works for me with JBoss-4.2.3.GA's bundled Hibernate 3.2.4.sp1 and ojdbc5 11.1.0.6.0 (both in JBoss global libs).
Update
Also recheck that an older version of hibernate is not present somewhere in classpath.
JBoss-Seam-2.2.0.GA distribution bundles hibernate 3.3.1.GA while Hibernate dialect for Oracle Database 11g? suggests that at least Hibernate 3.3.2+ is required for recent JDBC drivers.
JBoss-4.2.3.GA's bundled Hibernate 3.2.4.sp1 may have some modern staff backported.
I've never faced this kind of exception but to me it sounds very clear:
The Hibernate's DialectFactory should maintain some kind mapping of data base engine type
(including version) to the actual dialect. The whole issue is that you don't have a regitered mapping to Oracle 11
As a first bet I would take a look on this particular class. I don't know what version of hibernate do you have, but it looks like Oracle 11 is simply not supported, at least by the source I've found (Take a look here) Take a look on that ''MAPPERS'' hash map and you'll see... Open source rules here ;)
So I think the best would be upgrading the hibernate to the last version (just check that in the last version the mapper is updated).
Or at least debug the application server to figure out what does parameters are passed to the method and so.
Of course its also possible to build your custom version of Hibernate but I don't think it should be considered as a preferable solution.
I would also consider to override the default dialect as you've already found by yourself in 'that' article :) I don't see why it shouldn't work, but again you'd better debug it.
Maybe you should tell the JBoss somewhere that it should use your dialect as well...
Hope this helps
public String getDialectClass(int majorVersion) throws Throwable
{
switch(majorVersion)
{
case 8: // '\b'
return (DialectFactory.class$org$hibernate$dialect$Oracle8iDialect != null ? DialectFactory.class$org$hibernate$dialect$Oracle8iDialect : (DialectFactory.class$org$hibernate$dialect$Oracle8iDialect = DialectFactory._mthclass$("org.hibernate.dialect.Oracle8iDialect"))).getName();
case 9: // '\t'
return (DialectFactory.class$org$hibernate$dialect$Oracle9iDialect != null ? DialectFactory.class$org$hibernate$dialect$Oracle9iDialect : (DialectFactory.class$org$hibernate$dialect$Oracle9iDialect = DialectFactory._mthclass$("org.hibernate.dialect.Oracle9iDialect"))).getName();
case 10: // '\n'
return (DialectFactory.class$org$hibernate$dialect$Oracle10gDialect != null ? DialectFactory.class$org$hibernate$dialect$Oracle10gDialect : (DialectFactory.class$org$hibernate$dialect$Oracle10gDialect = DialectFactory._mthclass$("org.hibernate.dialect.Oracle10gDialect"))).getName();
case 11: // '\013'
return (DialectFactory.class$org$hibernate$dialect$Oracle10gDialect != null ? DialectFactory.class$org$hibernate$dialect$Oracle10gDialect : (DialectFactory.class$org$hibernate$dialect$Oracle10gDialect = DialectFactory._mthclass$("org.hibernate.dialect.Oracle10gDialect"))).getName();
}
throw new HibernateException("unknown Oracle major version [" + majorVersion + "]");
}
actually this is the code in DialectFactory so when your database version changes above 11 you will have this problem i have added extra switch case its resolved my problem
I am trying to create some beans using Spring and export them to RMI...
Here is my code:
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="OfferService" />
<property name="service" ref="offerService" />
<property name="serviceInterface" value="ro.project.services.OfferService" />
<property name="registryPort" value="1199" />
</bean>
I created a file called "policy.all" in my root folder and I am running my VM with that arguments but I still have this error:
java.lang.ClassNotFoundException: org.springframework.remoting.rmi.RmiInvocationHandler (no security manager: RMI class loader disabled)
I don't know what to do... in linux, the exact same project is running ok (with jdk 1.7.0.4) but in windows not... in java 1.5 (windows) it's working.. but in java 1.7.0.4 (windows) it's not working...
EDITED:
My error is:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.remoting.rmi.RmiServiceExporter#0' defined in class path resource [spring/services.xml]: Invocation of init method failed; nested exception is java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: org.springframework.remoting.rmi.RmiInvocationHandler (no security manager: RMI class loader disabled)
After adding this lines:
if (System.getSecurityManager() == null)
{
RMISecurityManager manager = new RMISecurityManager();
System.setSecurityManager(manager);
}
I have this error:
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [spring/application-context.xml]; nested exception is java.io.FileNotFoundException: class path resource [spring/application-context.xml] cannot be opened because it does not exist
thank you in advance
The point here is not to install a security manager but to find the class. You are missing some JAR file from your deployment.
I don't think it still important, but i personally face today the same issue, and cannot find answer. I post it here, maybe it helps someone.
Solution: stop rmiregistry program, or pass Spring jars to rmiregistry with -J option. Simplest way just stop rmiregistry and allow Spring to start another one with all required classes. And don't set up RMISecurityManager.
You need to have this in a part of your code:
System.setSecurityManager(new RMISecurityManager());
You can have another security manager as well, but there just has to be a security manager installed.
Actually the line I posted can be easily fired in the main class of a standalone desktop application, but I am not sure in your case. You should look for a configuration option doing this probably.
With Spring RMIServiceExporter, the Best Practice to manage correctly the RMI Registry is the use of RMIRegistryFactoryBean. To better permits you to understand, I paste an example of Spring configuration with a RemoteBean:
<bean id="RemoteServices" class="remote.RMIServicesImpl"/>
<bean id="RemoteRmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="alwaysCreate" value="true" />
<property name="port" value="1093"></property>
</bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="service" ref="RemoteServices" />
<property name="serviceInterface" value="remote.RemoteInterface" />
<property name="serviceName" value="RemoteServices" />
<property name="replaceExistingBinding" value="true"></property>
<property name="registry" ref="RemoteRmiRegistry"></property>
</bean>
In this way the RmiRegistryFactoryBean will manage autonomously everything about the RMI Socket Layer, and you don't need to stop the JVM, but simply redeploy it.
Please rate me if it works.
I have a really strange issue when using hibernate to connect to a MySQLDB and add data.
This is the error I get:
JDBC Driver class not found:
com.mysql.jdbc.Driver
This is how my hibernate.cfg.xml looks like
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/fpa-webapp</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
</session-factory>
</hibernate-configuration>
I dont understand why I see a 500 Error when I navigate to the application; it says that the driver is not found.
HTTP ERROR 500
Problem accessing /fpa-webapp/.
Reason:
Exception constructing service 'ValueEncoderSource': Error invoking
service builder method
org.apache.tapestry5.services.TapestryModule.buildValueEncoderSource(Map,
InvalidationEventHub) (at
TapestryModule.java:2287) (for service
'ValueEncoderSource'): Error invoking
service contribution method
org.apache.tapestry5.hibernate.HibernateModule.contributeValueEncoderSource(MappedConfiguration,
boolean, HibernateSessionSource,
Session, TypeCoercer, PropertyAccess,
LoggerSource): Exception constructing
service 'HibernateSessionSource':
Error invoking service builder method
org.apache.tapestry5.hibernate.HibernateCoreModule.buildHibernateSessionSource(Logger,
List, RegistryShutdownHub) (at
HibernateCoreModule.java:123) (for
service 'HibernateSessionSource'):
JDBC Driver class not found:
com.mysql.jdbc.Driver
I'm sure the driver is in the class path.
What it could be?
Your driver is not on the classpath.
There are two ways to ensure it's on the classpath:
Add it to the global lib directory. For Tomcat this is TOMCAT_HOME/lib.
Include it in the war.
It depends on your requirements which you use.
If you're going to use Tomcat to manage the connection pool, you'll need to add it to the TOMCAT_HOME/lib and instead of defining your datasource directly in the hibernate configuration, you'll reference it via jndi.
The only plausible explanation is that the Driver class is not on the CLASSPATH.
Check to make sure that the mysql-connector-java (or other relevant) jar is indeed in a place where it will get loaded. If you're 100% positive that it is, it might help to provide more information about how you know the class is being loaded, so that we can identify other possible causes.