org.springframework.jdbc.cannotgetjdbcconnectionexception Rmi class loader disabled - java

Rather new to Java coming from a c# background.
What I am trying to achieve is just to expose a method to jConsole via jmx and rim.
When I run my service and open jConsole I can see the method there and all looks good, now the problem comes in when i try to run this method via the console. The error I get is "Problem invoking helloWorld : java.rmi.UnmarshalException: Error unmarshaling return; nested exception is: java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException (no security manager: RMI class loader disabled)".
The method im trying to expose is
#ManagedOperation
public int helloWorld() throws Exception {
return jdbcTemplate.queryForInt(sql);
}
Here is my applicationContext file
<!-- this bean must not be lazily initialized if the exporting is to happen -->
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="assembler" ref="assembler" />
<property name="namingStrategy" ref="namingStrategy" />
<property name="autodetect" value="true" />
</bean>
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
<!-- will create management interface using annotation metadata -->
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<!-- will pick up the ObjectName from the annotation -->
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="jmxAttributeSource" />
</bean>
<context:component-scan base-package="com.bulks" />
<!-- enable annotations like #Autowired, which you also most likely need -->
<context:annotation-config/>
<bean class="com.bulksms.resources.HelloWorldResource"/>
<!-- setup basic datasource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/apu"></property>
<property name="username" value="root"></property>
<property name="password" value="password"></property>
</bean>
<!-- jdbcTemplate bean -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
What am i missing so my method can be executed from the console?
-----SOLUTION------
So after hacking away at this for long i tried to put the sql part in its own method and then just call the method in the helloWorld method.... Low and behold!!!! SUCCESS!!!
public int helloWorld() throws Exception {
setValueFromQuery();
return value;
}
private void setValueFromQuery() {
this.value = jdbcTemplate.queryForInt(sql);
}

You exception is a nested exception, so its happened on on your application,
java.lang.ClassNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException
So its say that there is a missing class, which could be the jdbc, make sure that you have it in your class path.
so if you have it, the check the connection criteria to your DB.

Related

Spring MVC 3.2.8: Create a new FileSystemXmlApplicationContext and loading the definitions from the given XML files

I have an Spring MVC 3.2.8 app, and I want to run StandAlone process to generate a PDF. I want to initialize the container and manage beans from an stand-alone app.
I have this piece of code:
public class CreatePDF {
private static final Logger LOGGER = Logger.getLogger (ImportEcolabelToolboxToECAT.class);
public static void main(String[] args) {
String[] configLocations = new String[] {
"C:/Development/Workspaces/EclipseWS/devices/deviceWeb/src/main/resources/com/nicinc/dao/dataAccessContext.xml",
"C:/Development/Workspaces/EclipseWS/devices/deviceWeb/src/main/webapp/WEB-INF/dao/databaseMessageSource.xml",
"C:/Development/Workspaces/EclipseWS/devices/deviceWeb/src/main/resources/com/nicinc/services/impl/servicesContext.xml",
"C:/Development/Workspaces/EclipseWS/devices/deviceWeb/src/main/webapp/WEB-INF/applicationContext.xml",
"C:/Development/Workspaces/EclipseWS/devices/deviceWeb/src/main/resources/com/nicinc/controller/propertyeditors/propertyeditorsContext.xml"};
FileSystemXmlApplicationContext ctx =
new FileSystemXmlApplicationContext(configLocations, true);
}
}
But I have this error when running the app.
Error creating bean with name 'dataSource': Invocation of init method failed; nested exception is 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
and here the definition from the file dataAccessContext.xml :
<!-- The PropertyPlaceholderConfigurer replaces placeholders in Spring bean definitions with the values from the chosen properties files. -->
<!-- There is an example use in the datasource definition below. Look for the $\{jdbc.*} values. -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/nicinc/dao/jdbc-test.properties</value>
<value>classpath:com/nicinc/dao/dbMessageSource.properties</value>
</list>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${hibernate.dialect}"/>
<property name="generateDdl" value="false"/>
<property name="showSql" value="false" />
</bean>
</property>
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
The javax.naming package comprises the JNDI Api. Since it is just an API its implementation you will have to provide. Generally the implementation is provided by App server. As per the error you are Missing the JNDI implementation.
Possible solution:
If you dont have any javaee related requirement then you should directly use DriverManagerDataSource.
You need to provide your own implementation.Below link might help.
using application data source locally.

How to give priority to spring bean with same id?

In our project we are using spring with Junit for Junit testing. We have used #ContextConfiguration annotation for loading multiple file. We have two classes AbstractContextJUnitTest and ContextJUnitTest and ContextJUnitTest extends AbstractContextJUnitTest.
During code flow I have noticed that same bean Id in multiple files with different bean types. When I am testing these Junits and getting the below error.
Error:
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean
named 'voterId' is expected to be of type [com.spring.test2.Student]
but was actually of type [com.spring.test2.Parent]
My requirement is Student bean should load with VoterId instead of Parent Bean.
Below are the java files and spring bean xml files:
test.xml:
<beans>
<context:annotation-config/>
<bean id="voterId" class="com.spring.test2.Parent">
<property name="Name" value="hai"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:xe" />
<property name="username" value="system" />
<property name="password" value="system" />
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
test1.xml
<beans>
<context:annotation-config/>
<bean id="voterId" class="com.spring.test2.Student">
<property name="name" value="hello"/>
<property name="number" value="2080"/>
</bean>
</beans>
AbstractContextJUnitTest.java
#ContextConfiguration(locations="classpath:/com/spring/test2/test1.xml")
public class AbstractContextJUnitTest extends AbstractTransactionalJUnit4SpringContextTests{
}
ContextJUnitTest.java
#ContextConfiguration(locations={"classpath:/com/spring/test2/test.xml"})
public class ContextJUnitTest extends AbstractContextJUnitTest{
#Test
public void testStudent(){
Student stud=applicationContext.getBean("voterId",Student.class);
assertEquals(stud.getNumber(), 2080);
}
}
Did you tried #Primary?
<bean id="voterId" class="com.spring.test2.Student" primary="true">
<property name="name" value="hello"/>
<property name="number" value="2080"/>
</bean>
You have to use #Qualifier for com.spring.test2.Parent wherever you need.
Or you can get the bean with type as:
applicationContext.getBeansOfType(Student.class).get("voterI‌​d")
This is probably because you have extended classes in that order..and your test.xml doesn't have any bean with of Student. So it is simply following inheritance and found parent.
Below lines make it look for bean voterid in test.xml first and it found it there.
ContextConfiguration(locations={"classpath:/com/spring/test2/test.xml"}) public class ContextJUnitTest

UnknownServiceException from hibernate [duplicate]

This question already has an answer here:
UnknownServiceException: Unknown service requested (Hibernate/Spring)
(1 answer)
Closed 7 years ago.
I'm using Spring 4 to set up my stuff that I'll need for using Hibernate 4. I have a SessionFactory autowired into my DAO layer. When I call sessionFactory.getCurrentSession() I get the error:
Exception in thread "MyImporterThread" org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
I've looked at many search results from Google (including a bunch from StackOverflow) on this exception, however none of them has struck me as the solution to my issue.
Here's my configuration:
spring-beans.xml:
<context:property-placeholder location="file:spring.properties" />
<context:component-scan base-package="com.company.scraping" />
<!-- Data Source -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver.class}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!-- Session Factory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.company.scraping" />
<property name="configLocation">
<value>file:scraping.db.hibernate.cfg.xml</value>
</property>
</bean>
<!-- Transaction Stuff -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- beans that are transactional or autowired -->
<bean id="scrapingDao" class="com.company.scraping.dao.ReportsScrapingDaoImpl" />
<bean id="scrapingService" class="com.company.scraping.service.ReportsScrapingServiceImpl" />
spring.properties:
jdbc.driver.class=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:#server:1521:testdb01
jdbc.user=user
jdbc.password=password
scraping.db.hibernate.cfg.xml:
<hibernate-configuration>
<session-factory>
<property name="connection.url">jdbc:oracle:thin:#server:1521:testdb01</property>
<property name="connection.username">user</property>
<property name="connection.password">password</property>
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.autocommit">true</property>
<property name="hibernate.generate_statistics">false</property>
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.show_sql">false</property>
</session-factory>
</hibernate-configuration>
Since this is not a web application, I use ApplicationContext context = new FileSystemXmlApplicationContext(args[0]) to initialize Spring.
My service class is autowired (not shown in the config because I have to type all this out), and contains an autowired instance of the DAO. This is what the DAO looks like:
#org.springframework.stereotype.Repository
#org.springframework.transaction.annotation.Transactional
public class ReportsScrapingDaoImpl implements ReportsScrapingDao
{
#Autowired
#Qualifier("sessionFactory")
private SessionFactory sessionFactory;
#Override
#Transaction(readOnly = true)
public List<Stuff> getAll()
{
Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Stuff.class);
... (more code)
}
}
The code bombs out when sessionFactory.getCurrentSession() is called. I've tried using sessionFactory.openSession() as well, but it gave the same results. I'm not sure what's going on here.
I did a last-ditch search and this turned up. Eclipse outputs a compiler warning, complaining that there may be a resource leak because the ApplicationContext is never closed. I added a line at the very end of my main method (after all the Threads had been started) to close the ApplicationContext. Once I got rid of the line that closes the ApplicationContext, the problem went away.
Moral of the story is that your ApplicationContext should not be closed until you no longer need anything from it--so you should probably never close it.

Cannot get Spring to export annotations to JMX

I can't for the life of me get Spring to export metadata about my JMX beans.
I have Spring configured as follows:
<bean id="attributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
<property name="attributeSource" ref="attributeSource"/>
</bean>
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
<property name="attributeSource" ref="attributeSource"/>
</bean>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="autodetect" value="true"/>
<property name="namingStrategy" ref="namingStrategy"/>
<property name="assembler" ref="assembler"/>
</bean>
I have an MXBean interface defined like this:
#ManagedResource
public interface MyMXBean {
#ManagedOperation(description="My description.")
#ManagedOperationParameters({
#ManagedOperationParameter(name = "myParam", description = "My param description.")
})
public void foo(String someParameter);
}
My bean appears in jconsole, but it does not display the associated metadata, so I don't get an operation description or correct parameter name/description.
Can anyone tell me what I'm doing wrong?

JMX MBean registration using Spring on a standalone JVM

Following various example configurations from Spring documentation as well as some forums on the Internet, my application context file looks like:
<beans>
<bean id="dH" class="abc.def.ghi.DH">
<constructor-arg>
<value>0</value>
</constructor-arg>
<property name="num" value="100"/>
</bean>
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=dH1" value-ref="dH"/>
</map>
</property>
</bean>
<bean class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
</beans>
I'm running this without any container and on plain JVM. I'm able to connect to my process via JConsole but the MBean doesn't show up. However registering the bean programmatically exposes it successfully.
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
DH dh = new DH(0);
mbeanServer.registerMBean(dh, new ObjectName("bean:name=dH1"));
I've tried playing with the Spring configuration without success. I think the bean is not registering to the already running MBean server that was accessible from ManagementFactory.getPlatformMBeanServer().
Any ideas on the issue?
In addition to defining an MBeanServerFactory bean (as Nicholas noted in their answer) using ...
<bean class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
... you need to tell the MBeanExporter what to manage:
If a bean implements one of the JMX management interfaces, MBeanExporter can simply register the MBean with the server through its autodetection process.
If a bean does not implement one of the JMX management interfaces, MBeanExporter will create the management information using the supplied MBeanInfoAssembler.
Assuming your abc.def.ghi.DH class does not implement any JMX interface, try defining your MBeanExporter as:
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="assembler">
<bean
class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler"
>
<property name="managedMethods">
<list>
<value>getNum</value>
</list>
</property>
</bean>
</property>
<property name="beans">
<map>
<entry key="bean:name=dH1" value-ref="dH"/>
</map>
</property>
</bean>
Looking at the OpenJDK 7, update 2, build 21 DefaultMBeanServerInterceptor.java source, line 898 creates a DynamicMBean for regular objects:
DynamicMBean mbean = Introspector.makeDynamicMBean(object);
I haven't debugged it, but I bet mbeanServer.registerMBean(dh, new ObjectName("bean:name=dH1")) eventually calls DefaultMBeanServerInterceptor.registerObject(), which creates a DynamicMBean for you and properly registers your standard JavaBean properties' setters and getters.
Here are some test files that work using Spring Framework 3.0.5 and Oracle HotSpot Java 1.6.0_24. After setting your CLASSPATH environment variable, just run javac *.java and java Main and use VisualVM (or similar application) to connect to the running java application to see the registered MBeans.
ac.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans
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.xsd"
default-lazy-init="true"
>
<bean id="test" class="Test" />
<bean class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="assembler">
<bean
class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler"
>
<property name="managedMethods">
<list>
<value>getVal</value>
<value>setVal</value>
</list>
</property>
</bean>
</property>
<property name="beans">
<map>
<entry key="bean:name=Test" value-ref="test"/>
</map>
</property>
</bean>
</beans>
Test.java:
public class Test {
private String val = "";
public String getVal() {
return val;
}
public void setVal(String v) {
val = v;
}
}
Main.java:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(final String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("ac.xml");
try {
Thread.sleep(1000 * 60 * 5);
} catch (final Throwable t) {}
}
}
The issue is with the MBeanServerFactoryBean.
From the javadoc:
By default, MBeanServerFactoryBean will always create a new
MBeanServer even if one is already running. To have the
MBeanServerFactoryBean attempt to locate a running MBeanServer first,
set the value of the "locateExistingServerIfPossible" property to
"true".
Try this config:
<bean class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
=================================================
Try specifying the MBeanServer in the exporter bean:
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=dH1" value-ref="dH" />
</map>
</property>
<property name="server" ref="MBeanServer" />
</bean>
<bean id="MBeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
========================================================================
Ok, let's take the brute force approach and acquire the platform MBeanServer directly:
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="beans">
<map>
<entry key="bean:name=dH1" value-ref="dH" />
</map>
</property>
<property name="server">
<bean id="MBeanServer" class="java.lang.management.ManagementFactory" factory-method="getPlatformMBeanServer"/>
</property>
</bean>

Categories