java.lang.NoClassDefFoundError – Not Again?
The inspiration for this blog was all the frustration experienced over a period of 1 month with the all too familiar(esp. for Java developers) exception java.lang.NoClassDefFoundError.
As sun and moon existed from ages, the runtime exception NoClassDefFoundError has existed since the time of Classes. If an issue has existed over such a period, how come I had to struggle for 1 month to resolve this issue.( Its a relief that I resolved it 🙂 )? Were there not enough forum questions resolved? Were there no blogs addressing this issue?
Yes, there are hundreds of forum questions and many blogs on the same issue. But, still I was stuck. Stuck in a no-man’s land without much clue. Lets have a short re-cap:
I started my search for the steps to use external libraries in Web Dynpro DC. There were many useful blogs in this pursuit:
1. How to use external libraries in the SAP component model (PART II)
2. bertram.ganz: How to use external JAR files in … | SCN
With the help of these blogs, I began my development. It all seems too simple. Create an external library, wrap it in j2ee server DC and use that DC is in WD DC. It seemed like a breeze.
Step 1: External Library
I created an external library. Then, exposed the library as public part. Key here: Two separate public parts – One for assembly and one for compilation. I figured out the exact reason after couple of exceptions. The compilation part is used for the purpose of build and assembly part is used by the j2ee server DC for server deployment. The assembly part at times is encapsulated the included jar files into a single jar. The screenshot 1 has assembly part holding the individual jar file. Screenshot 2 shows the assembly part having a single jar for all the included jar files.
Screenshot 1 Screenshot 2
Note: You can always copy the jar file into local drive and unzip it into folder to find the exact contents in the jar. If at times build is not executed properly, the folder may not contain the included jar files. Refer screenshot 3 for the jar file – opened as folder. Screenshot 3
Step 2: Include the Library Public part in the J2EE server DC and deploy.
I tried to create a J2EE Enterprise appln. DC. The assembly public part( of external library) was included in the DC and deployed. However, the deployment aborted and with it my heart skipped a beat. The error:
java.rmi.RemoteException: Error occurred while deploying ear file ./temp/deploy/work/deploying/extlibear.ear. Reason: None of the available containers recognized the components of application com.dicv.fuso/extlibear; it is not possible to make deploy.
(message ID: com.sap.sdm.serverext.servertype.inqmy.extern.EngineApplOnlineDeployerImpl.performAction(DeploymentActionTypes).REMEXC)
Inspite of all possible queries and attempts this issue is still pending. Even an SAP Note resulted in a link to another blog and not a resolution.
Now, to fulfill the requirement to deploy the jar in a DC, a J2EE library DC was created. The assembly part was added as used DC and deployed onto the server successfully. I started to breathe.
The steps 2 was seemingly finished. Not it was just about step 3 and the task was complete. No, it wasn’t.
Before I move to step 3, the important points in this step are:
- Build the J2EE library DC. Please inspect the .sda file which is generated after the DC build. I found that at occasions my build process has the included assembly jar of individual jar files from the external library. But, at times the jars are not included. Its good to do a re-build and push it through editor.
- Inspect the deployed DC in the visual admin to ascertain the availability of the jar on the server.
- Inspect the provider.xml file in the .sda ( open in folder ) -> server -> provider.xml. Refer: Screenshot 4.1 and 4.2. The provider.xml must include the jar files in the folder.
Screen shot 4.1
Note: This point was my roadblock. I actually focused my attention on library references, instead an incorrect build resulted in the issue.
Step 3: Use the deploy DC in the WD DC and code using the external jar.
I included the compilation public part of external library and the deploy DC public part ( defLib – created by the editor ). The jxl jar files were detected and I was able to write the code to recieve a file and obtain its sheet name.
I completed the build and deployed. I ran the application. Then, my nemesis: java.lang.NoClassDefFoundError occurred.
I figured that it must something simple. I was in for a shock.
Back to present:
I was in panic mode very quickly. I started created fresh DCs and testing. I started removing existing DCs. I started repeating the steps everyday but the result remianed same. At some trials, even the jxl jars did not detect and I felt I needed some external treatment not external library. I frantically approached all java colleagues and they seemed more shocked by the roundabout way of using an external library rather than actual class loader issue. Their only response was, the classes are not available at runtime. How I wish the solution was so simple.
Finally, after inspection of the sda files, I was able to pinpoint the issue towards an incorrect build. Later a successful build and deployment and I was able to read the selected excel.
Life has moved on to bigger things but this issue shall remain with me. At some level, it was caused by a sense of panic, a level of ignorance and lack of patience. But, in my opinion, the main cause for this delay was my over-confidence or a causal approach towards the task.
My biggest learning point: No task is of low-priority. Everything is criticial for the functioning of the application. A small issue can hold back the complete project.
We should be careful of every issue, which occurs or may occur and prepare the necessary solution for them.
Hope the users were not bored and felt that the blog was a repetition of the old blogs. It was my experience and hope other developers can use this experience .
Its a wonderful blog!!! Having same issues in excel upload. And presently this runtime
error "java.lang.NoClassDefFoundError: jxl/Workbook".
Can u please explain these?
The DC will be located in the workspace. Right click on the project and find the path(generally in C drive). Locate the DC and open the .sda file using an archive program like.zip or .7zip.
This step is just verify. But initially ensure that you have done all the necessary steps related to adding dependency, usage - compile and assembly time and other steps related to external library usage in a DC.
While adding dependency in J2EE DC, there are two Check boxes-Deploy time/run time when i click on the dependent DC(External Library DC). What should I select here?? or Let me leave it as it is?
I have added external library DC as used component in J2EE library DC. When i build the DC and verified gen/default/deploy folder the jar file does nott exists .
Sakti, refer to the blog links mentioned in my blog, regarding the selection of compile time and runtime dependency of public part usage. basically, you create 2 public parts, one for compile time so that jar files are recognized by compiler and other one to be recognized during the runtime.
Revisit the blogs for exact steps and validate your project with those steps.