Monday, November 09, 2009

System.Data.OracleClient requires Oracle client software version 8.1.7 or greater

Yes, they are many resources on the web about this problem, but none helped me. And because I encountered this problem twice and did not remember how I solved it, I thought of posting this, at least as a note to self.
The solutions on web suggest that you are not allowed to read/execute some dlls in the oracle client because rights on that folder are not properly configured. Not the case. Real problem: Missing MSVCR71.dll. Problem with Oracle 10g Instant Client on Vista and Windows 7. Discovered this by using ProcMon to see what my application is searching for in the oracle client folder. The same way I discovered I was missing the Network\admin folder where tnsnames.ora files should be located.

Monday, January 26, 2009

org.ajax4jsf.config.ParsingException: No filter mapping set for a filter

It goes something like this:


ERROR [[/WaSFP]] Exception starting filter richfaces
javax.servlet.ServletException: Error parse web application config

Caused by: org.ajax4jsf.config.ParsingException: No filter mapping set for a filter richfaces
at org.ajax4jsf.config.WebXMLParser.init(WebXMLParser.java:131)
at org.ajax4jsf.config.WebXMLParser.init(WebXMLParser.java:199)

It seemed strange, because I had defined a filter mapping and It worked for me before, so why not now? I had something like this in my web.xml:

<!-- Richfaces configuration-->
<context-param>
<param-name>org.richfaces.SKIN</param-name>
<param-value>blueSky</param-value>
</context-param>
<filter>
<display-name>RichFaces Filter</display-name>
<filter-name>richfaces</filter-name>
<filter-class>org.ajax4jsf.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>richfaces</filter-name>
<servlet-name>Faces Servlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>Faces Config</servlet-name> <!-- wrong, 'Faces Servlet' here-->
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Config</servlet-name> <!-- wrong again, 'Faces Servlet' here-->
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

Eclipse 3.4 with JBoss tools - Richfaces VPE 3.0.0 CR1. Nerver trust the IDE :)

Saturday, December 06, 2008

EJB testing: second thought

I had proposed a way of testing EJBs outside the container. The problem would that is that it wouldn't be normal to test a bean who's life cycle depends heavily on the container outside of it. The solution would be an embedded server, such as emdedded Glassfish

I am not sure it currently has EJB support, I couldn't find information to clear things out, but it's on it's way. Digging a little, I found that they are other EJB embedded containers out there, like OpenEJB(the EJB 3 container for Apache Geronimo and WebSphere Community Edition) or Embedded JBoss. The vision here, a Java EE 6/EJB 3.1 vision, would be to have something like this:


@RunWith(EmbeddableEJB3Runner.class)
public class PlaceBidTest {
@EJB
private PlaceBid placeBid;

@Test
public void testAddBid() {
placeBid.addBid(new Bid("rrahman", 10059, 200.50));
}
}

Now this is beautiful :)

Tuesday, October 28, 2008

naive EJB testing

EJB can't and shouldn't be tested as POJO's. It would contradict with the simple concept of 'container managed bean'. Plus, if you use injection for PersistanceContext, UserTransaction, SessionContext etc, no container will be there to inject values and you will be happy if you only see 'Null Pointer Exceptions'.

Still, for simplicity, you can test EJB outside the container, provided that you manually call methods that are marked as Life-Cycle Callbacks (@PostConstruct, @PrePassivate etc.). Also, I will describe a way for injecting a PersistenceContext outside of the container.

First of all, you normally declare an EntityManager something like this:


@PersistenceContext
private EntityManager entityManager;
//or
@PersistanceUnit(unitName="PU")
private EntityMangerFactory emf;

Now, to be able to set a value to it when it is running outside the contianer, I suggest providing a setter for it. In the test class, you first instantiate an EntityManager like this:


EntityManagerFactory emf = javax.persistence.Persistence.createEntityManagerFactory("testPU");
instance.setEntityManager(emf.createEntityManager());


The testPU referenced has to have a RESOURCE_LOCAL transaction type, that is a non-jta datasource. Also, the datasource has to be reachable from the project (e.g. not be defined in the application server config files). The short solution would be to declare it using the element, by provind the url, username, password, driver. TopLink configuration would look something like this:


<properties>
<property name="toplink.jdbc.driver" value="org.postgresql.Driver"/>
<property name="toplink.jdbc.url" value="jdbc:postgresql://localhost:5432/huddi"/>
<property name="toplink.jdbc.password" value="super"/>
<property name="toplink.jdbc.user" value="postgres"/>
</properties>

Wednesday, May 14, 2008

Dynamic web service call in Java

How do I call a web service programatically, knowing only the URL of WSDL describing the service. I have thought of two options, each with it's pro's and con's.

1. Executing wsimport. This means executing this command from code, passing parameters such as wsdl url or folder where to import. After this, using a ClassLoader, load the serivice class, wich always has service.getQName().getLocalPart(), where service is a javax.wsdl.Service. This means parsing the wsdl, with a tool such as wsdl4j. Then, find the methods that have @WebEndpoint addnotation, using Reflection API ... then load that class, then find the parameters needed and finally invoke. Sounds complicated? It is, but comparing to

2. Use Dispatch API. This means creating the SOAP message by hand. And this is the hard part. What if a web service method requires complex types? Parse the wsdl and find them. But they are not always in the wsdl, they can be in an attached xsd schema. Hmm ..... And what if the webservice is using WS-Policy, WS-Addresing or some other WS-* standard? Parse the wsdl to find how to construct the SOAP message. And .... configure headers.

I think using wsimport is a much simple way, even if it may take more time to complete the task. You can easily configure security or addresing. And even if it sound complicated, it is much simpler to implement.

Friday, April 11, 2008

Interoperable WSS using JDBC realm in Glassfish

Web Service Security is a very useful mechanism, but can be a little tricky if you want to ensure it's interoperability. Also, in an enterprise application, user authentication should be done against a database. So in this blog I want to show that this is actually an easy thing, especially when using NetBeans and Glassfish tandem.

I used a development version of NB 6.1, the one from april 6, then RC1 as soon as it appeared. I was a little unhappy with the Beta release because it had a numerous of bugs. RC1 is much better and I can see a HUGE improvement on my home computer, an old Pentium M@1.6Mhz. The autocomplete is much faster, startup also. It starts faster then Eclipse:).
What I would like to see in the future is a better Seam plugin and a visualization of a normal JSP page, not a Visual Web JSF. If it would have this, it would be the perfect IDE for me. Also, in Eclipse, I like how I can deploy my application quickly and modifications done on a JSP do not require a redeploy of the application. Something like this should also be in NetBeans&Glassfish.
In terms of Desktop Applications and Web Services, NetBeans rules. Swing Application Framework is very good and Web Service support is amazing: restful, stateful, secure, interoperable ... everything. Nice ...


Ok, so let's begin. The first thing you should do is create a database. You need to have a user and role table, as seen in the image below(the fields marked in blue are necessary)

Now, we need to configure a JDBC realm in Glassfish. To do this, we start the server and select "View admin console". We login to the admin console. First, create a JDBC resource under Resources. Then, navigate to Configuration -> Security -> Realms -> new. Under classname, we select the JDBC realm. The configuration should look like this:



Under Digest Algorithm, you can optionally specify a hash algorithm. Only the hash of the password should be kept in the database; when an user authenticates itself, the system will make a hash of the password using this algorithm and compare it to the database. When inserting a new user, you can use the fallowing code to make a hash from a password:

private static final char[] HEXADECIMAL = { '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

public static String hashPassword(String password) {
try {
MessageDigest md = MessageDigest.getInstance("SHA");
md.reset();

byte[] bytes = md.digest(password.getBytes());
StringBuilder sb = new StringBuilder(2 * bytes.length);
for (int i = 0; i < low =" (int)" high =" (int)">> 4);
sb.append(HEXADECIMAL[high]);
sb.append(HEXADECIMAL[low]);
}
return sb.toString();
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(UsersFacadeBean.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}

Now, we can create the application. In NetBeans, create a new Enterprise application. First, let's configure the authentification. Add a Glassfish Deployment Descriptor. This will create a sun-application.xml. Here, map the groups from the database to the roles in the application and the realm to use, like this:

<sun-application>
<security-role-mapping>
<role-name>superuser</role-name>
<group-name>superuser</group-name>
</security-role-mapping>
<security-role-mapping>
<role-name>user</role-name>
<group-name>user</group-namev
</security-role-mapping>
<security-role-mapping>
<role-name>admin</role-name>
<group-name>admin</group-name>
</security-role-mapping>

<realm>realm</realm>
</sun-application>
Next, create a web service in the EJB module, for example. You can also create one in the web project, but you can't use @RolesAllowed in a servlet web service, so for now let's stick to EJB web service.
After creating a web service, righ-click and select Web Service -> Add Operation. Configure the name and parameters. You might ask why use the 'Add Operation' instead of manually writing the method. The answer is that by doing this, the IDE also configures the message parts and headers to be signed/encrypted if using WSS.
Now add @RolesAllowed({"admin", "superuser"}) for the method. This will allow only users in the specified role to call this method. Now, add the action attribute at the @WebMethod with the same value as the operationName. This is to make sure that the .NET client will correctly generate the service proxy.

To configure security, go to Web Services from the project tree and rightclick Edit Web Service Attributes. Under Quality of Service, select "Secure Service" with "Development Defaults" and "Username authentification with symmetric key".

If at runtime you want to determine the user who called the method, do the fallowing:
1. inject a WebServiceContext with @Resource
2. Use the fallowing code:

javax.security.auth.Subject subject = (javax.security.auth.Subject)wscontext.getMessageContext().get("CLIENT_SUBJECT");
Object[] principals = subject.getPrincipals().toArray();
String username = ((Principal)principals[0]).getName();

return username;

And this is all, we have all set up. Now for the client.
A Java client is easy, just generate a web service client and configure security using NetBeans the same way you did on the EJB. If you want to configure the username and passwor dynamicly, you can do like this:

YourService service = new YourService();
Your port = service.getYourPort();

((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "insert_username");
((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "insert_password");


Now for a .NET client. A little bit tricky if not done properly.
First, you have to create a certificate from the keystore.key. You cand find instructions on how to create a certificate from keystore here. Install this certificate as a Personal certificate. You can use the 'certmgr.msc' tool to make sure you've done it correctly.

I have used Visual Studio 2008 and .NET framework 3.5, but it should work with .NET 3.0 also. Using Visual Studio, generate a proxy for the Java web service. There are some modifications that have to be done in app.config for the generated stub. You have to add a
<identity>
<dns value="xwssecurityserver">
</dns>
</identity>
in the endpoint tag . This will specify the truststore alias to be used.


This is the code you have to add to securely call the webservice:

YourServiceClient port = new YourServiceClient();
port.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser,
System.Security.Cryptography.X509Certificates.StoreName.My,
System.Security.Cryptography.X509Certificates.X509FindType.FindByIssuerName, "SUNCA");
port.ClientCredentials.UserName.UserName = "insert_username";
port.ClientCredentials.UserName.Password = "insert_password";
Now you can call any method of the web service.
And there you have it, all done! Secure interoperable web service.

NOTE: I have used the default keystore that comes with Glassfish. In a real application, you should create your own keystore.