Search code examples
javajsonjdeveloper

new JSONObject triggers java.lang.NoClassDefFoundError


I'm developing a custom authentication plugin for OAM(Oracle Access Manager) in Java language using JDeveloper IDE.


i'm parsing a URL and i get the variables i want from a JSONObject correctly on a Main.class file without triggering any kind of Exception

This leads me to the assumption that the whole parsing code is correct which means the readJsonFromUrl function does it job.


Let me mention what my PhillPlugin.class includes

  1. public ExecutionStatus process(AuthenticationContext context) , triggered when the Plug-In is to run.
  2. public void getDataGenerate(String Url), called inside process function to created the JSONObject from URL
  3. public static JSONObject readJsonFromUrl(String url) called inside getDataGenerate function
  4. private static String readAll(Reader rd) used for parsing inside readJsonFromUrl

Now i upload the Plug-In to the server, i run it and get the following in it's Logs

java.lang.NoClassDefFoundError: org/json/JSONObject
    at phillplugin.PhillPlugin.readJsonFromUrl(PhillPlugin.java:184)
    at phillplugin.PhillPlugin.getDataGenerate(PhillPlugin.java:132)
    at phillplugin.PhillPlugin.process(PhillPlugin.java:63)

What is needed in order to create the Plug-In:

  • PhillPlugin.class
  • PhillPlugin.xml
  • MANIFEST.MF

I'm mentioning the above because i have to include somewhere in these files the org.json path. ( it already exists as an import in PhillPlugin.class and Main.class )

The org.json.jar is included in Project's Libraries as well as all the .jars in order to build the Plug-In


MANIFEST.MF

Manifest-Version: 1.0
Bundle-Version: 10
Bundle-Name: PhillPlugin
Bundle-Activator: phillplugin.PhillPlugin
Bundle-ManifestVersion: 2
Import-Package: org.osgi.framework;version="1.3.0",oracle.security.am.plugin,oracle.security.am.plugin.authn,oracle.security.am.plugin.impl,oracle.security.am.plugin.api,oracle.security.am.common.utilities.principal,oracle.security.idm,javax.security.auth
Bundle-SymbolicName: PhillPlugin
CLASSPATH: felix.jar, identitystore.jar, oam-plugin.jar, utilities.jar, org.json.jar

Sample of the PhillPlugin.Class

I'm not supposed to include the URL for security purposes. (Trust me it's Valid)

    public void getDataGenerate(String Url) {
        System.out.println("-----   Reading Json Object  -----");
                       JSONObject json;
        try {
            json = readJsonFromUrl(Url);
            System.out.println("The Json Object: "+json.toString());
            otp=Integer.parseInt((String) json.get("otp"));
            System.out.println("The User is:"+user+"\n"+"His OTP is: "+otp);
        } catch (Exception e) {
            System.out.println("Exception : "+e.toString());
        }          

    public static JSONObject readJsonFromUrl(String url) throws IOException,JSONException {
        System.out.println("Opening Stream");
        InputStream is = new URL(url).openStream();
        System.out.println("Stream opened");
        try {
         System.out.println("----------\n\n\nUrl to Parse: "+url+"\n\n\n");
          BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
          System.out.println("\n\n\n"+"BufferedReader opened\n\n\n\n");
          String jsonText =(String) readAll(rd);
          System.out.println("\n\n\nJsonTEXT:"+jsonText+"\n\n\n");
            JSONObject json=null;
            System.out.println("\n\n Created Json Instance\n\n\n");
            try{
                System.out.println("inside try statement - initializing JSONObject with the text above \n\n\n");
             //-------ERROR TRIGGERED HERE---------
             json = new JSONObject(jsonText);
                System.out.println("--------------------Object created-------------------");
            }catch (Exception e) {
                System.out.println("\n\n\n\n\nJSONOBJECT failed to be created: \n"+e);
            }
          System.out.println("\n\n\nJSON OBJECT"+json+"\n\n\n\n");
          return json;
        } finally {
          is.close();
        }

    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
          sb.append((char) cp);
        }
        return sb.toString();
      }

PhillPlugin.xml

<Plugin type="Authentication">
    <author>uid=Phill</author>
    <email>phill@oracle.com</email>
    <creationDate>12:47:00, 2019-07-11</creationDate>
    <description>Phill-Plugin Prints Hello</description>
    <configuration>
    </configuration>
</Plugin>


This is the output on server Logs before crashing:


Stream opened
----------
Url to Parse: https://something

BufferedReader opened

JsonTEXT: it's correct

Created Json Instance

inside try statement - initializing JSONObject with the text above 

I'm worrying too much about the MANIFEST.MF file because probably i'm doing something wrong in there

Sorry for the long post, i will provide any extra information if needed, Thank you


Solution

  • When writing an Authenticaiton Plugin for OAM Server , all extra libraries should be mentioned in MANIFEST.MF as well as the external .jar files.

    Furthermore , all .jar files should be deployed in the final plugin .jar as well as the external libraries

    In my case i had to include org.json.jar at the exported PhillPlugin.jar as follows:

    • PhillPlugin.jar

    enter image description here

    as you can see both org.json.jar and it's libraries org are required

    • Manifest.MF

    The last step is to mention in MANIFEST.MF all the extra classes that you are using in your plugin

    In my case i had to include this in my Import-Package Attribute in order to be able to create a JSONObject instance

    org.json;resolution:=optional,
    org.json.JSONObject;resolution:=optional
    

    If you would like to use a JSONArray you had to add this:

    org.json.JSONArray;resolution:=optional
    

    and so on.

    Edit: The class-path should be mentioned as follows:

    Bundle-ClassPath: org.json.jar, felix.jar, identity-provider.jar, oam-plugin.jar, utilities.jar