LDAP Queries are very slow on SSL (Java - SpringFramework) - spring

We have a web application in Java (Spring Framework). For authentication and user management, we are using SSO with LDAP.
The LDAP context is as defined in the bean below:
<bean id="legacyLdapContext" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="ldaps://aaa.bbb.ccc.edu:636"/>
<property name="base" value="cn=Users,dc=bbb,dc=ccc,dc=edu"/>
<property name="userDn" value="user"/>
<property name="password" value="*****"/>
<property name="pooled" value="true"/>
<property name="baseEnvironmentProperties">
<map>
<entry>
<key>
<value>java.naming.security.authentication</value>
</key>
<value>simple</value>
</entry>
<entry key="java.naming.referral">
<value>ignore</value>
</entry>
</map>
</property>
</bean>
Everything works fine, but the connection/queries are very slow.
If the same configuration is changed to non ssl (`ldap://aaa.bbb.ccc.edu:389') it is lightening fast. A query that takes the non SSL context just a few seconds, takes the SSL context 7 minutes.
Is there any LDAPS related configuration missing? I have installed the certificate to JVM using the steps here http://javacolors.blogspot.in/2012/05/how-to-register-ssl-certificates-in.html .

To force the JVM to pool SSL connections, add the following line to your Apache Tomcat /bin/setenv.sh ({{setenv.bat}} for Windows) file
On Linux:
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.jndi.ldap.connect.pool.protocol='plain ssl' -Dcom.sun.jndi.ldap.connect.pool.authentication='none simple DIGEST-MD5'"
On Windows:
JAVA_OPTS=%JAVA_OPTS% -Dcom.sun.jndi.ldap.connect.pool.protocol="plain ssl" -Dcom.sun.jndi.ldap.connect.pool.authentication="none simple DIGEST-MD5"
https://confluence.atlassian.com/display/CROWDKB/Performance+problem+when+using+LDAPS

Related

JaxWsPortProxyFactoryBean to bypass SSL checks

I have an Spring Proxy as a client to access some WS:
<bean id="clientPort" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
<property name="serviceInterface" value="com.acme.IClient"/>
<property name="serviceName" value="sercie"/>
<property name="endpointAddress" value="https://com.acme.IService"/>
<!-- ... -->
</bean>
<bean id="client" class="com.acme.Client">
<property name="theClientPort" ref="clientPort"/>
</bean>
Since it runs in JBoss, i know it uses CXF, now i want to bypass SSL checks, presumably with a HttpConduit, but i cannot setup system variables nor affect the configuration for the rest of CXF clients.
If i could access the object in code i would setup the HttpConduit, but ((Advised) proxy).getTargetSource().getTarget() returns null, (maybe i'm missing some configuration in web.xml)

JBoss AS 7.1 Remoting JMX Not working

I have an MBean (JMX) which is exposed through RMI in a JBoss AS 7.1 Server but I can't access it. I already follow all of the tutorials revolving around but it just cant work.
This is how I exposed my MBean
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean id="mBeanExporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry
key="test:name=foo"
value-ref="foo" />
</map>
</property>
<property name="server" ref="mbeanServer" />
</bean>
<bean id="registry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="1399" />
</bean>
<bean id="serverConnector"
class="org.springframework.jmx.support.ConnectorServerFactoryBean">
<property name="objectName" value="connector:name=rmi" />
<property name="serviceUrl"
value="service:jmx:rmi://192.168.1.108/jndi/rmi://192.168.1.108:1399/myconnector" />
<property name="server">
<ref local="mbeanServer" />
</property>
</bean>
How can I remotely access this in Jconsole ?
I've already tried these:
service:jmx:remoting-jmx://192.168.1.108:9999
service:jmx:rmi:///jndi/rmi://192.168.1.108:1090/jmxrmi
service:jmx:rmi:///jndi/rmi://192.168.1.108:1090/myconnector
And many more but none of those work.
What am I doing wrong or what should I do ?
On JBoss 7 /EAP6 is can't use rmi for remote jmx calls, JBoss uses remoting-jmx protocol for jmx.
You can see a full example in: Using Spring to call jmx bean on JBoss7 / EAP 6

Cloudbees, Tomcat, and Spring: "Cannot create JDBC driver of class '' for connect URL 'null'"

I'm trying to deploy my Spring MVC webapp (Hibernate and JPA) to a Tomcat 7 ClickStack in Cloudbees, but cannot seem to configure the database connection properly. I've tried following multiple tutorials (which offer many solutions), none of which have worked. If someone could take a look at my config files below and let me know if they see anything wrong it would be greatly appreciated.
The error:
java.lang.NullPointerException
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
First, I bound my database to my app using the cloudbees cli so that I don't have to declare it in cloudbees-web.xml:
bees app:bind -a myapp/app -db mydatabase
application - myapp/app bound to cb-db:myapp/mydatabase as mydatabase
(I have also tried unbinding the database and defining it in cloudbees-web.xml and also in context.xml without success)
spring-data.xml:
<jee:jndi-lookup id="datasource" jndi-name="jdbc/mydatabase"
lookup-on-startup="false" proxy-interface="javax.sql.DataSource"
cache="true" resource-ref="true" />
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="hibernate-jpa"/>
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="showSql" value="false"/>
<property name="generateDdl" value="true"/>
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
web.xml:
<resource-ref>
<res-ref-name>jdbc/mydatabase</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I have removed all references to connectors from my Maven files and all jars from the lib folder. Searching for the error message shows that it usually has to do with the driver not being found... but since the database is supplied by the container, why do I have to worry about that?
-- EDIT: Working META-INF/context.xml file --
Note that the com.cloudbees.jdbc.Driver referenced in a lot of the docs didn't work (threw a classnotfound exception), so I had to package the mysql-connector-java.jar file in the lib folder. Also, for now I just hardcoded the url, username, and password instead of setting it up to use the system properties.
<Context>
<Loader delegate="true"/>
<Resource
name="jdbc/mydatabase"
auth="Container"
type="javax.sql.DataSource"
maxActive="5"
maxIdle="2"
username="USERNAME"
maxWait="5000"
driverClassName="com.mysql.jdbc.Driver"
password="PASSWORD"
url="jdbc:mysql://MY_EC2_DB_URL:3306/mydatabase"/>
</Context>
I was facing the same issue and finally managed to "properly" configure the datasource !
I'm using a PropertyPlaceholderConfigurer as follows :
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="false" />
<property name="database" value="MYSQL" />
<property name="generateDdl" value="false" />
</bean>
<context:property-placeholder system-properties-mode="FALLBACK" />
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${dt4j.driver}" />
<property name="url" value="${dt4j.url}" />
<property name="username" value="${dt4j.username}" />
<property name="password" value="${dt4j.password}" />
</bean>
"FALLBACK" indicates placeholders should be resolved against any local properties and then against system properties.
Finally, I just need to add system properties (-Dprop=value) or add them in the Cloudbees deployer plugin to make it work.
There must be a better way but the main goal is achieved : the data source configuration is not hardcoded in the project !
Unfortunately at this point in time, the JNDI DB setup is not done for you in the tomcat7 stack.
When you bind the database to your app - it injects some system properties:
MYSQL_PASSWORD_MYDB
MYSQL_URL_MYDB
MYSQL_USERNAME_MYDB
(MYDB as it is the name of your db resource). You can then refer to them in your code/config.
For tomcat 7, you can put in /META-INF/context.xml into your app which will set up the JNDI data source (see http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html)

how to make connection pool in spring application using BasicDataSource

I have created the application in which I need to configure the connection pool.In which I am configuring the connection pooling in the spring_Config file. using the Basicdatasource.
but there is some problem to create the connection pool. Please tell me how to create the connection pooling in spring application using BasicDatasource.
I tried this one code in spring config ;-
bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource">
com.mysql.jdbc.Driver
jdbc:mysql:/revup?noAccessToProcedureBodies=true
jdbc:mysql://localhost:3306/revup?noAccessToProcedureBodies=true</value>-->
</value>-->
</value>-->
<property name="poolPreparedStatements">
<value>true</value>
</property>
<property name="initialSize">
<value>2</value>
</property>
<property name="maxActive">
<value>15</value>
</property>
Is there any modification of code please tell me. thanks in advance.
Here's a working example:
<bean id="dataSourceApache" class="org.apache.commons.dbcp.BasicDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/coffee_shop" />
<property name="username" value="john" />
<property name="password" value="secret" />
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
If you're using Eclipse, you should also download support for XML configuration syntax. It really helps you alot.
SpringSource Tool Suite has all the SpringSource support bundled ready for use.
Else, you can see all the fields that's possible to set in the Java documentation.

Start the H2 database in server mode via Spring

I'm trying to start the H2 database in server mode (I want it to run in a different process) via Spring.
Currently I'm using java Runnable.exec to start the h2 database (using the command: "java -cp h2.jar org.h2.tools.Server")
I know that there is a way to do it via Spring. I tried to add the following to the spring configuration, but it didn't work (it didn't start the H2 database):
<bean id="org.h2.tools.Server" class="org.h2.tools.Server"
factory-method="createTcpServer" init-method="start" destroy-method="stop">
<constructor-arg value="-tcp,-tcpAllowOthers,true,-tcpPort,8043" />
</bean>
<bean id="org.h2.tools.Server-WebServer" class="org.h2.tools.Server"
factory-method="createWebServer" init-method="start">
<constructor-arg value="-web,-webAllowOthers,true,-webPort,8082" />
</bean>
I would appreciate any help/ideas
Do you happen to have:
<beans default-lazy-init="true" ...
in your Spring configuration files?
Recently I had to do the same configuration to make unit test and check data, this works for me (Spring 3.1.4). Then you just have to connect with jdbc:h2:tcp://localhost:8043/mem:test and make sure to put a while(true){} at the end of your test.
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver"/>
<!--property name="url" value="jdbc:h2:mem:;TRACE_LEVEL_FIlE=4"/-->
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean class="org.h2.tools.Server" factory-method="createTcpServer" init-method="start" destroy-method="stop">
<constructor-arg>
<array>
<value>-tcp</value>
<value>-tcpAllowOthers</value>
<value>-tcpPort</value>
<value>8043</value>
</array>
</constructor-arg>
</bean>
Are you sure the createTcpServer method in the Server class is really called? Have you tried setting up a breakpoint there?
H2 tutorial claims this how you can create and start the server programmatically:
import org.h2.tools.Server;
...
// start the TCP Server
Server server = Server.createTcpServer(args).start();
...
// stop the TCP Server
server.stop();
Your Spring definition seems to mimick the same initialization. But you can always try doing it manually - maybe it's some fault in Spring configuration.
EDIT:
I've tried your configuration and it works for me. What makes you think the server is not started? It doesn't print out anything on stdout, however the process listens at the 8043 port. So it seems pretty OK.

Resources