JPA embedded sample

During my last talk on Betabeers, titled “Introduction to Java EE”, I was asked if JPA and Bean Validation could be used in stand-alone applications. I had seen some examples of those utilizations, but, to be perfectly honest, I had never used, so I’ve written a small sample that shows how to use JPA and Bean Validation in that context. Please, follow this link to review my source code.


Upgrading JasperReports Server

I’ve just upgraded my JasperServer installation from version 4.2.1 to 5.2.0 I followed the chapter 9 of the JasperReports Server community project installation guide, release 5.2.0, all ran properly and I logged on using the user jasperadmin. The former version used to authenticate its users connecting to a Microsoft Active Directory, the manual says at this point:

“Configuration modifications, such as client-specific security classes or LDAP server configurations, need to be hand-copied from your previous environment and re-integrated into the upgraded environment”

So, I copied the LDAP server configuration I described on my post JasperServer user authentication with Microsoft Active Directory, I restarted tomcat and tried to log on using my Active Directory credentials, but the access was denied. I reviewed the server log and I read the following exception:

org.springframework.beans.NotReadablePropertyException: Invalid property ‘principal.fullName’ of bean class [org.springframework.security.providers.UsernamePasswordAuthenticationToken]: Bean property ‘principal.fullName’ is not readable
or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:729)
at org.springframework.beans.BeanWrapperImpl.getPropertyValue(BeanWrapperImpl.java:721)

After researching on the Internet, I edited the file applicationContext-security-web.xml and added the filter in bold:

/**=httpSessionContextIntegrationFilter,encryptionFilter,multipartRequestWrapperFilter,
webAppSecurityFilter,jsCsrfGuardFilter,${bean.loggingFilter},${bean.userPreferencesFilter},
delegatingAuthenticationProcessingFilter,${bean.userPreferencesFilter},${bean.basicProcessingFilter},
delegatingRequestParameterAuthenticationFilter,JIAuthenticationSynchronizer,
anonymousProcessingFilter,delegatingExceptionTranslationFilter,filterInvocationInterceptor,
switchUserProcessingFilter,iPadSupportFilter

I restarted the application server and Active Directory authentication became available again.


References


How to assemble an standalone application using Maven

I’m a newbie at Maven, but I’m becoming a fan. Today I’d like to talk about a simple task, which Netbeans performs automatically in Ant based standalone project but doesn’t in Maven ones, assembling the library dependencies in a lib folder along with the jar file:

JMSBasicClientScreenshot

First of all, I had to add the Maven Dependency plugin to my pom.xml file, this action created a folder called dependency in my Maven target directory when a built the project:


<plugin>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <phase>process-sources</phase>
      <goals>
        <goal>copy-dependencies</goal>
      </goals>
      <configuration>
        <outputDirectory>${targetdirectory}</outputDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Later on, I also put the Maven JAR plugin with a configuration in order to add the CLASSPATH to the manifest file, using the same prefix (lib) I wanted to use in the assembly:


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifest>
        <addClasspath>true</addClasspath>                            
        <classpathPrefix>lib/</classpathPrefix>                            
        <mainClass>com.wordpress.fcosfc.JMSBasicClient</mainClass>
      </manifest>
     </archive>
  </configuration>
</plugin>

The following task was writing a custom assembly descriptor for the Maven Assembly plugin and putting in the folder src/main/assembly:


...
<id>bin</id>
<formats>
  <format>zip</format>
</formats>
<fileSets>
  <fileSet>
    <directory>${project.build.directory}</directory>
    <outputDirectory>/</outputDirectory>
    <includes>
      <include>*.jar</include>
    </includes>
  </fileSet>
  <fileSet>
    <directory>${project.build.directory}/dependency</directory>
    <outputDirectory>lib</outputDirectory>
  </fileSet>
</fileSets>
...

Finally, I had to add the Maven Assembly plugin to my pom.xml file:


<plugin>
  <artifactId>maven-assembly-plugin</artifactId>
  <version>2.4</version>
  <configuration>
    <descriptors>
      <descriptor>src/main/assembly/customAssembly.xml</descriptor>
    </descriptors>
  </configuration>
  <executions>
    <execution>
      <id>make-assembly</id> 
      <phase>package</phase> 
      <goals>
        <goal>single</goal>
      </goals>
    </execution>
  </executions>
</plugin>

References


Fighting with sockets!

Last week, I was appointed to develop a Java program that should connect to an external secure socket, in order to get data provided by a partner company. Another requisite was that the module should be stored on an Oracle 11g Database, so I must use a 1.5 JDK. Easy, I thought!

First of all, I review Java Secure Socket Extension (JSSE) Reference Guide. Our company partner IT team provided me with the key store containing the certificate I should trust and I decide to program a custom SSL context:

   ...
   KeyStore keyStoreTrust = KeyStore.getInstance("PKCS12");
   keyStoreTrust.load(this.getClass().getResourceAsStream("KeyStoreTrust.pfx"),
                      "password".toCharArray());
   TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
   trustManagerFactory.init(keyStoreTrust);

   SSLContext sslContext = SSLContext.getInstance("SSL");
   sslContext.init(null, trustManagerFactory.getTrustManagers(), null);
   ...

The first problem arose when the server socket (developed in Microsoft .NET C#) unexpectedly closed the connection during the handshake, the support guy of my partner company said me that they got the following error message: “The client and server cannot communicate, because they do not possess a common algorithm”. Therefore, I delved into the problem and finally I realized that the server wanted to use a TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA cipher suite, which wasn’t supported by the security providers shipped with the JDK 1.5 I’d like to point out that a key point to find out the source of the error was to activate the debug of the SSL connection:

System.setProperty("javax.net.debug", "ssl");

Hence, I decided to add to my program the well-known Bouncy Castle security provider, which supports the required cipher suite and it’s 1.5 compliant:

Security.addProvider(new BouncyCastleProvider());

Once I sorted out the problem, everything started to work properly, at least as an stand-alone client! So, I created a “Loadjava and Java Stored Procedures” profile in my JDeveloper IDE, in order to deploy the software to the Oracle Database 11.2, but when I tried to do it I got the following errors:

Invoking loadjava on connection 'Test11g_Paco' with arguments:
 -order -resolve -definer -thin -resolver ((* TEST) (* PUBLIC) (* -)) -synonym
 errors   : class org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey
 ORA-29552: verification warning: java.lang.NoClassDefFoundError: java/security/interfaces/ECPrivateKey

 errors   : class org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey
 ORA-29552: verification warning: java.lang.NoClassDefFoundError: java/security/interfaces/ECPublicKey

 errors   : class org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PrivateKey
 ORA-29552: verification warning: java.lang.NoClassDefFoundError: java/security/interfaces/ECPrivateKey

 errors   : class org/bouncycastle/jcajce/provider/asymmetric/ecgost/BCECGOST3410PublicKey
 ORA-29552: verification warning: java.lang.NoClassDefFoundError: java/security/interfaces/ECPublicKey

 errors   : class org/bouncycastle/jce/provider/JCEECPrivateKey
 ORA-29552: verification warning: java.lang.NoClassDefFoundError: java/security/interfaces/ECPrivateKey

 errors   : class org/bouncycastle/jce/provider/JCEECPublicKey
 ORA-29552: verification warning: java.lang.NoClassDefFoundError: java/security/interfaces/ECPublicKey

 Loadjava finished.

I can’t understand the problem because the interfaces java.security.interfaces.ECPublicKey and java.security.interfaces.ECPrivateKey are available in 1.5 and the Oracle Database 11.2 JVM is supposed to be 1.5 compliant, but I couldn’t find any satisfactory solution.


JasperReports Server & Linux CentOS

I’ve recently installed JasperReports Server (release Community Project 4.2.1) on Linux CentOS, so I would like to talk about some issues I’ve been dealing with.

First of all, I have to write about a JRStyledTextParser exception that I got and didn’t have on Microsoft Windows. Once more a forum post was the beginning of the solution, so I edited the file $JASPERSERVER_HOME/apache-tomcat/scripts/clt.sh and set the property java.awt.headless=true:

export JAVA_OPTS="-Djava.awt.headless=true ..."

I wanted to run JasperServer as a service so I had to code the following script in /etc/init.d:

#!/bin/bash
#
# jasperserver        
#
# chkconfig: 2345 95 15
# description: Script de inicio de JasperReports Server

RETVAL=$?
JASPERSERVER_HOME="/jaspersoft/jasperreports-server-cp-4.2.1"

case "$1" in
 start)
        if [ -f $JASPERSERVER_HOME/ctlscript.sh ];
          then
            echo $"Starting JasperReports Server"
            /bin/su - jasperadmin -c "$JASPERSERVER_HOME/ctlscript.sh start"
        fi
        ;;
 stop)
        if [ -f $JASPERSERVER_HOME/ctlscript.sh ];
          then
            echo $"Stopping JasperReports Server"
            /bin/su - jasperadmin -c "$JASPERSERVER_HOME/ctlscript.sh stop"      
        fi
        ;;
 restart)
        if [ -f $JASPERSERVER_HOME/ctlscript.sh ];
          then
            echo $"Restarting JasperReports Server"
            /bin/su - jasperadmin -c "$JASPERSERVER_HOME/ctlscript.sh restart"
        fi
        ;; 
 status)
        if [ -f $JASPERSERVER_HOME/ctlscript.sh ];
          then
            /bin/su - jasperadmin -c "$JASPERSERVER_HOME/ctlscript.sh status"      
        fi
        ;;
 *)
        echo $"Usage: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac

exit $RETVAL

After that, I added the service:

chmod 755 jasperserver
chkconfig --add jasperserver

Finally, I used a specific user jasperadmin as the owner of JasperServer software, this user could not open the restricted ports 80 and 443 (I needed HTTPS), so I set up Apache to act as a proxy, adding this line to the httpd.conf configuration file:

ProxyPass / ajp://jasperserver.test.local:8009/

I hope that my experience will be useful for you!


JasperServer user authentication with Microsoft Active Directory

I was appointed to evaluate JasperServer last week and I have to say that I’m really pleased with this Open Source reporting server, specially from my developer’s point of view, because it’s fully integrated with iReport IDE, which I had previously used to design JasperReports that I embed in my Java Swing Applications.

One of the requisites was that the product could be integrated with an Microsoft Active Directory infrastructure, so our systems administration team could setup and maintain the server in a quick and easy way. Although the user guide of my version (community project, release 4.1) referred to an “External Authentication Cookbook”, I just could found a former version on the Internet (release 3.5) and there are some differences, so I’d like to write about my findings. thus you don’t have to spend a morning configuring a simple test environment.

First of all, you have to edit the <application-server-path>/jasperserver/WEB-INF/applicationContext-security.xml config file, in my case C:\Program Files\jasperreports-server-cp-4.2.1\apache-tomcat\webapps\jasperserver\WEB-INF\applicationContext-security.xml, locate the bean authenticationManager and uncomment the line <ref local=”ldapAuthenticationProvider”/> , so your system will search for users in Active Directory first.

The next step is to look for the bean ldapContextSource, uncomment the lines and point to one of your domain controllers, using the credentials of an user that can read the directory. Here you have an example:

<bean id="ldapContextSource">
   <constructor-arg value="ldap://dc01.test.local:389/dc=test,dc=local"/>
   <property name="userDn">
      <value>CN=administrator,CN=Users,DC=test,DC=local</value>
   </property>
   <property name="password">
      <value>p@ssw9rd</value>
   </property>
</bean>

The next bean to configure is the userSearch one, changing the default constructor argument (uid={0}) by (sAMAccountName={0}) and setting up the DN root where you have configured your user accounts:

<bean id="userSearch">
  <constructor-arg index="0">
    <value>OU=USERS_OU</value>
  </constructor-arg>
  <constructor-arg index="1">
    <value>(sAMAccountName={0})</value>
  </constructor-arg>
  <constructor-arg index="2">
    <ref local="ldapContextSource" />
  </constructor-arg>
  <property name="searchSubtree">
    <value>true</value>
  </property>
</bean>

The last step is to change some values into the ldapAuthenticationProvider configuration, here you have an excerpt of  the one running on my test server, so you can compare with yours:

<bean id="ldapAuthenticationProvider"
      class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
  <constructor-arg>
    <bean class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
      <constructor-arg><ref local="ldapContextSource"/></constructor-arg>
      <property name="userSearch"><ref local="userSearch"/></property>
    </bean>
  </constructor-arg>
  <constructor-arg>
    <bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
      <constructor-arg index="0"><ref local="ldapContextSource"/></constructor-arg>
      <constructor-arg index="1"><value>OU=GROUPS_OU</value></constructor-arg>
      <property name="groupRoleAttribute"><value>CN</value></property>
      <!--property name="groupSearchFilter"><value>((member={1})(CN=*))</value></property-->
      <property name="searchSubtree"><value>true</value></property>
    </bean>
  </constructor-arg>
</bean>

Finally, I’d like to point out that it is not a good idea to have your Active Directory passwords navigating as clear text through the insecure HTTP protocol, so it’s a good idea to change the default security constraints, in order to use the HTTPS protocol, enabling SSL into the <application-server-path>/jasperserver/WEB-INF/web.xml file. Please, review the Apache Tomcat documentation to enable HTTPS, taking into account that the JasperServer bundled Tomcat server uses APR.


Debugging Java Stored Procedures

I’ve been a fan of developing Java software stored in Oracle Databases for the last years, it’s the perfect partner of PL/SQL,  where this structured language is difficult to deal with or simply can’t achieve the goal.

One of my first problems was remote debugging, a common issue for every programmer.

First of all, I asked my DBA for the DEBUG CONNECT SESSION system privilege. When I got it, I had to configure my JDeveloper project for remote debugging, I started using the version 10g of this powerful IDE, so I changed the project properties in order to listen for JPDA (Java Platform Debugger Architecture) connections:

Project properties for remote debugging, JDeveloper 10g

Nowadays, I’m working with JDeveloper 11g, where I have to configure a Run/Debug/Profile within the project properties, clicking on the Remote Debugging check-box of the Launch Settings and adjusting the same parameters of the former version:

Project properties for remote debugging, JDeveloper 11g

Later on, the next step was to set the breakpoints I needed in the code, so I could go to the menu Run → Debug, in order to listen for remote debugging sessions. At this point, I was asked for the details of the connection:

Listening process parameters

Once I started the listening process, I could check for it checking the Run Manager.

The next step was to run SQL*Plus (nowadays I use SQLDeveloper), logging on the Database and calling the procedure dbms_debug_jdwp.connect_tcp with two VARCHAR2 parameters: the IP direction of my PC and  the port where my IDE was listening for JPDA connections.

After that, I started my debugging session calling the PL/SQL wrapper from SQL*Plus.

When I finished my debugging session, I ran the procedure dbms_debug_jdwp.disconnect from SQL*Plus and I used the Run Manager of JDeveloper to terminate the listening process.

Finally, I would like to talk of some problems I’ve suffered from: sometimes the debugger disconnects the session without any reason, others it disconnects when the Java code throws an exception in order to be managed by the calling PL/SQL, both times the Oracle Database connection is finished too.