Wednesday, September 13, 2017

Mystic Cybersource Error Message


  • "UsernameToken authentication failed" - that means you might have a invalid SOAP key. In our case, I had a few extra line breaks in the key. 
  • "Merchant password has expired" - the SOAP key has expired

NOTE: Cybersource has 3 different security keys, one for Security Acceptance (SA key), one for Silent Order Post (SOP key) and one for SOAP (SOAP key). Make sure you generate the right one to replace your old key!

Wednesday, October 8, 2014

Debugging maximum open cursors issue in Java code

If you have some legacy database operations in your java code, sometimes your application will stop working after a while. When you look at your server log, you find something like this:


java.sql.SQLException: ORA-01000: maximum open cursors exceeded
...

Usually you can temporarily solve the problem by restarting the server. But it will come back at you when database connection running out of open cursors again.

Root Cause

The issue here is that every database connection can only have a fixed number of open cursors (defined as the maximum open cursors in the Oracle database). When your code run a query statement, it will open a cursor; when you close the statement, the cursor will be closed. However, sometimes programmers want to run two different queries in the same block of code, and they forget  
to close the first one before using the second. For example:

    PreparedStatement statement = null;
    ResultSet result;
    try {
      // is user an alumnus
      statement = connection.prepareStatement(
          "SELECT package1.is_alum(?) FROM dual ");
      statement.setString(1, _id);
      result = statement.executeQuery();
      
      if (result.next()) {
        _isAlum = result.getInt(1)==1?true:false;

      }

      // is user a student
      statement = connection.prepareStatement(
          "SELECT package1.is_student(?) FROM dual ");
      statement.setString(1, _id);
      result = statement.executeQuery();
      
      if (result.next()) {
        _isStudent = result.getInt(1)==1?true:false;

      }
    }
    finally {
      if (statement != nullstatement.close(); 
    } 
    

The problem is that even though we close the prepared statement at the end, the first statement to check if user is an alum is never closed - a leaked open cursor!

Debug 

So how do you debug such a problem? The server log usually will not tell you where the unclosed statement is. It just informs you that a certain database operation can not run because maximum open cursors are reached. You need to go to the database itself, run a query to find out the SQL statement with the must open cursors:

SELECT s.machine, oc.user_name, oc.sql_text, count(1) cnt
FROM V$OPEN_CURSOR OC, V$SESSION S
WHERE OC.SID = S.SID 
GROUP BY USER_NAME, SQL_TEXT, MACHINE
HAVING COUNT(1) > 9
ORDER BY COUNT(1) DESC

You will get a result like this:

machine      user_name  sql_text                                cnt
my.host.com  ADMIN SELECT package1.is_alum(:1 ) FROM dual 413

Now we know the problem is of this sql statement, so search your java code for a substring of the statement (i.e. search "package1.is_alum" in this case), and then close the statement!


Solution

    PreparedStatement statement = null;
    ResultSet result;
    try {
      // is user an alumnus
      statement = connection.prepareStatement(
          "SELECT package1.is_alum(?) FROM dual ");
      statement.setString(1, _id);
      result = statement.executeQuery();
      
      if (result.next()) {
        _isAlum = result.getInt(1)==1?true:false;

      }

      if (statement != null) statement.close();

      // is user a student
      statement = connection.prepareStatement(
          "SELECT package1.is_student(?) FROM dual ");
      statement.setString(1, _id);
      result = statement.executeQuery();
      
      if (result.next()) {
        _isStudent = result.getInt(1)==1?true:false;

      }
    }
    finally {
      if (statement != nullstatement.close(); 
    } 

Wednesday, November 28, 2012

Set up Eclipse with Maven, Glassfish and Debug

Prerequisite:
  • Eclipse IDE for Java EE Developers Juno Release installed
Install SVN/Maven/Glassfish plugins:
  • Help -> Install New Software...
  • Install subclipse plugin (from: http://subclipse.tigris.org/update_1.8.x)

          (Notes: SVNkit setup instruction can be found here)
  • install Eclipse WTP plugin (from: http://download.eclipse.org/webtools/repository/juno)
  • install m2e - Maven Integration for Eclipse plugin (from: http://download.eclipse.org/technology/m2e/releases/)
  • install Maven Integration for WTP plugin (from: http://download.jboss.org/jbosstools/updates/m2eclipse-wtp/)
  • install GlassFish Application Server plugin (from: http://download.java.net/glassfish/eclipse/juno)

Maven build your project:
  • svn check out a project from your svn repository
  • in "Jave EE" perspective, "Project Explorer" window, right click on your project, "Configure -> Convert to Maven Project"
  • From the top menu, "Run -> run configurations...", add a few maven commands:
    • maven build (set goals as "package")
    • maven rebuild (set goals as "clean package")
    • maven clean (set goals as "clean")
  • Check "Skip Tests" if you don't want to run unit test when you do maven build on your local machine
  • Add maven command as "Run Favorites" in the "run" button: 
  • Select "mvn rebuild" from the green "run" button on the top tool bar to build your project
Set up Glassfish
  • Open Servers Window: Window -> Show View -> Servers
  • Right click in the severs window to add a new server
  • Choose a glassfish domain for the server



Deploy project on glassfish
  • in "Jave EE" perspective, "Project Explorer" window, right click on your project, "Run As -> Run on Server".
Setup debug

  • From top menu: Run -> Debug Configurations... -> Remote Java Application -> New
  • Make sure you put in the correct host name and glassfish debug port (in my case: localhost and 8099)
  • Click on "Debug" button to start debugging.

Friday, June 8, 2012

Associate new file type with Netbeans velocity editor plugin

I just installed Netbeans Velocity Editor plugin, by default it only supports *.vm and *.vsl file types. But we use *.vtl as velocity template in our projects.

To enable the velocity support for *.vtl file type, go to "Tools" -> "Options" -> "Miscellaneous" -> "Files", click "New ..." to add a new file extension, then select "text/x-velocity" for "Associated File Type (MIME)", click "Ok".

Netbeans 7.0.1 context menu (right click) very slow

For some reason the context menu of my Netbeans 7.0.1 was really really slow. Sometimes it took more than 30 seconds for it to show after I right click on a class or variable.

I tried to deactivate a few plugins: Restful service, SOAP service, Hibernate, etc according to my google search on the similar issue. But none of them worked.

Finally I decided to upgrade my Netbeans to the latest version of 7.1.2. And the problem is solved!


Thursday, April 12, 2012

Drupal site structure change couldn't be saved

We have a huge site structure in drupal 6. After we upgraded php 5.2.6 to 5.3.3, we got a fatal error when trying to access the site structure page:


Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 82 bytes) in .....

So we have to put this line in %drupal_home%/sites/default/settings.php:

ini_set('memory_limit', '512M');

This increased the drupal memory limit from 128M bytes to 512M bytes. Now we can see the site structure page. However, when we tried to make some changes, the changes are not saved and no error on the web page. Then we found this warning in the apache error log:

[error] [client xxx.xxx.xxx.xxx] PHP Warning:  Unknown:
Input variables exceeded 1000. To increase the limit change max_input_vars in php.ini. in Unknown on line 0, referer: https://yoursite.com/menu-site-structure

So now we added this line to php.ini:

max_input_vars = 2000

This increased the max input variables from 1000 (default) to 2000, and this solved the problem.


Thursday, April 5, 2012

Debugging Drupal Source Code remotely in NetBeans

Configuring the Server:


1. Make sure PHP XDebug module is installed.
2. Add this section to your php.ini (i.e. /etc/php.ini).  NOTE: make sure you put IP address of the client machine (the debugging computer) for the "remote_host", not the the server IP!

; xdebug config
xdebug.remote_enable=on
xdebug.remote_host=%client IP address%
xdebug.remote_port=9000
xdebug.remote_log=/var/log/xdebug.log
xdebug.idekey=netbeans-xdebug

3. Restart Apache (i.e. $apachectl graceful).
4. Run php -info. And you should see something like this:

xdebug support => enabled
Version => 2.1.4
... 
DBGp - Common DeBuGger Protocol => $Revision: 1.145 $
...
xdebug.idekey => xxxxx => netbeans-xdebug
xdebug.remote_enable => On => On
xdebug.remote_handler => dbgp => dbgp
xdebug.remote_host => xxx.xxx.xx.xxx => xxx.xxx.xx.xxx
xdebug.remote_port => 9000 => 9000
...

Configuring the Client:

1. Make sure PHP plugin is installed for the NetBean.
2. Start NetBeans and create a new PHP project (File->New Project). Select PHP Application from Remote Server and click Next.
3. Give the project a name and local location and click Next.
4. Setup the Remote Connection as appropriate for your server and click Next. Click the "Manage" button the set the remote connection by putting in the username and password. If you use SSH to access the server, leave the password field blank but provide the private key file.
5. NetBeans will construct a list of files it will download. Click Finish to download the files.

Debugging Drupal Remotely:

1. Make sure you open the port for Netbeans if you use Windows 7 and Vista.
2. In Netbeans, set the drupal project as the main project, then go to "Debug Project".
3. Enjoy debugging.