Friday, July 27, 2012

OracleJSP: oracle.jsp.provider.JspCompileException

Work with OC4J and seen this?

500 Internal Server Error

OracleJSP: oracle.jsp.provider.JspCompileException:
Errors compiling:\product\10.1.3.1\OracleAS_1\j2ee\home\application-deployments\TOLTAT\TOLTAT-webapp\persistence_pages
_index.java

Line # Error
18

cannot access HttpServletRequest bad class file: .\HttpServletRequest.class class file contains wrong class: javax.servlet.http.HttpServletRequest Please remove or make sure it appears in the correct subdirectory of the classpath. public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException {

(Click to expand.)

The fix is depressingly simple. Delete all the .class files from $ORACLE_HOME/j2ee/home/*.class. You don't need to bounce the server after this.

Friday, June 29, 2012

Query Results as CSV in Oracle SQL Developer

I have been using Oracle SQL Developer a lot this week, and have been exporting query data as CSV a lot too: right clicking on the results > selecting Export and going through the dialogs.

Now there is a super cool much easier way. Run your SQL like this:

select /*CSV*/* from MYTABLE;

Then just select all on the results screen and copy/paste the results directly into an Excel spreadsheet! Unfortunately you have to select all twice if you have more than 500 results (you can't override Tools > Preferences > Database > Advanced > SQL Array Fetch Size to be greater than 500).

Thanks to Jeff Smith's blog post: Formatting Query Results to CSV in Oracle SQL Developer. Thanks as well to Ian Carpenter's answer on this StackOverflow question: how to export query result to csv in Oracle SQL Developer?


Actually this isn't working for me in Oracle SQL Developer 3.0.04 - Jeff Smith's solution says you run script (F5) and all I see then is text output of the query i.e. tab delimited, no quotes.. *sigh*

Monday, June 25, 2012

Table names should be upper case with Oracle

I am working with Oracle XE (Oracle Database 10g Express Edition Release 10.2.0.1.0) and the wonderful DB tool DbVisualizer. I am doing some data analysis and am using DbVisualizer to import data from Excel into a new table so that I can run some SQL over it. DbVisualizer even creates the table for you (dropping any existing table first if need be). So very quickly I have a table called PoBoxCompare with all my data in it. Next I do a quick sanity test to make sure the data is there. Using DbVisualizer's auto-complete I have my test SQL:

select * from ROB.PoBoxCompare;

Uh-oh, it doesn't exist!

17:34:49  [SELECT - 0 row(s), 0.000 secs]  [Error Code: 942, SQL State: 42000]  ORA-00942: table or view does not exist
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.000/0.000 sec  [0 successful, 0 warnings, 1 errors]

After some head scratching and experimentation, I find that table names (in Oracle at least) are case sensitive. If you have a table name with mixed case, you need quotes around the name.

select * from ROB."PoBoxCompare";

Of course, the better solution is just to make sure your table names are all upper-case, which is what I am doing now. :)

Note: the exact same rule applied to column names too!

Monday, June 18, 2012

Use WinMerge as your TortoiseSVN Diff Tool

It is very easy to modify Tortoise for SVN (on Windows) to use the magnificent WinMerge as its diff tool.

Right click on a source managed file > select TortoiseSVN > Settings > drill down to External Programs > Diff Viewer > click External for "Configure the program used for comparing different revisions of files" and enter the path C:\Program Files (x86)\WinMerge\WinMergeU.exe -e -s -x -ub -dl %bname -dr %yname %base %mine.

Note 1. Make sure the path to WinMergeU.exe is correct!

Note 2. I have been using this for ages already, but the "-s" argument is a neat recent addition for me - to force WinMerge to use just a single instance.

Thursday, June 07, 2012

MelbJVM meetup #4

Last night I attended the 4th Melbourne Java & JVM Users Group meeting, and it was fantastic! Here are the highlights.

  • Pizza, beer, over 30 40 developers all talking to each other.
  • JBehave. The first speaker was Aaron Walker who gave a presentation and short demo on JBehave. JBehave is about Behaviour Driven Development - it's a way of writing tests in plain English and is perfect when you need to communicate tests to (or collaborate on tests with) other teams such as BAs or testers. A quick example is below.

    Scenario: User signs up with invalid data
    Given I am on the sign up page
    When I fill in "Email" with "invalid email"
    And I submit the sign up form
    Then I should see error messages

    The scenarios can easily be written by testers or BAs or devs. The Given, When, And and Then clauses get matched to actual Java test code through annotations, e.g.

    @When("I fill in $email with $data")
    public void enterEmailAddress(
          @Named("email) String email,
          @Named("data" String data) {
       // ...
    }
  • Technology Radar by ThoughtWorks. The second speaker was Scott Shaw from ThoughtWorks who presented a register of technologies and techniques that ThoughtWorks maintain called Technology Radar: http://www.thoughtworks.com/radar. It is essentially a survey of a wide variety of tech options ThoughtWorks thinks you should Adopt, Trial, Assess or Hold (avoid)! Important Adopt items included REST, HTML 5, polyglot persistence (relational DBs are not the only option) and polyglot programming (Java is not the only language that runs on the JVM). Interesting Avoid items included Enterprise Service Bus, Java Portal Servers, GWT and Dart.

    I think one of the most important Adopt topics Scott discussed was Infrastructure as Code: there are so many tools now that automate the setting up of a server. You should be able to completely automate the initialisation of a server, it's configuration and deployment of all applications/DBs. These automation scripts etc are infrastructure that should be treated just like code: kept in source control and executed as needed. The consequence of this approach is that you shouldn't need admins to continually log into systems to configure them - human involvement means room for manual error: adjust a script, trash and re-create the server as needed.

Thursday, May 24, 2012

Connect to a JMX server and query an MBean attribute

Here is some sample code to connect to a JMX server and query an MBean attribute.

// Connect to JMX Server.
JMXServiceURL u = new JMXServiceURL(   "service:jmx:rmi:///jndi/rmi://HOSTNAME:PORT/jmxrmi");
JMXConnector c = JMXConnectorFactory.connect(u);

// Get an MBeanServerConnection on the remote VM.
final MBeanServerConnection remote = c.getMBeanServerConnection();

// Construct the fully qualified name of the bean.
ObjectName beanName = new ObjectName("APPNAME:type=BEANTYPE,name=BEANNAME");

// Query an attribute on the MBean.
System.out.println(remote.getAttribute(beanName, "ATTRIBUTENAME"));;

The code is simpler if you are running it from the same container within which the beans are being registered.

// If you are running code within the same container as the beans are
// being registered from, it is much easier to get the connection.
MBeanServer mbsvr = MBeanServerFactory.newMBeanServer();

// And the bean name is also much simpler.
ObjectName beanName = new ObjectName(mbsvr.getDefaultDomain() + ":type=BEANTYPE,name=BEANNAME");

// Query an attribute on the MBean.
System.out.println(remote.getAttribute(beanName, "ATTRIBUTENAME"));;

Pages that will help you learn more are below.

Friday, March 09, 2012

I don't know what kind of terminal you are on - all I have is 'cygwin'

When I SSH to a SunOS Box from Cygwin on Putty (puttycyg) on Windows and attempt to use vi, I get the following:

I don't know what kind of terminal you are on - all I have is 'cygwin'

This fix is easy enough, and I got the clue from this forum post: Solaris 10, PuTTY, and vi. Edit ~/.profile or ~/.bashrc and add the following:

TERM=xterm; export TERM

Tuesday, March 06, 2012

Using proxy with authentication in PHP reCAPTCHA

When using PHP reCAPTCHA, you need to modify the _recaptcha_http_post method to use a proxy with username and password as per below.

Thanks to Eli Fulkerson's blog post, Recaptcha via proxy server that showed me how to add proxy support. Thanks to lcollet on this Drupal code page for the clues to add username and password.

function _recaptcha_http_post($host, $path, $data, $port = 80) {

   $proxy_host = 'PROXY-HOST';
   $proxy_port=PROXY-PORT;
   $proxy_username='PROXY-USERNAME';
   $proxy_password='PROXY-PASSWORD';

   $req = _recaptcha_qsencode ($data);

   $http_request  = "POST http://$host$path HTTP/1.0\r\n";
   $http_request .= "Host: $host\r\n";
   $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
   $http_request .= "Content-Length: " . strlen($req) . "\r\n";
   $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";

   if (!empty($proxy_username)) {
      $auth_string = base64_encode($proxy_username . ($proxy_password != '' ? ":{$proxy_password}" : ''));
      $http_request .= "Connection: close\r\n";
      if ( !empty($auth_string ) ) $http_request .= "Proxy-Authorization: Basic {$auth_string}\r\n";
   }

   $http_request .= "\r\n";
   $http_request .= $req;

   $response = '';
   if( false == ( $fs = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 10) ) ) {
      die ('Could not open socket');
   }

   fwrite($fs, $http_request);

   while ( !feof($fs) )
      $response .= fgets($fs, 1160); // One TCP-IP packet
   fclose($fs);
   $response = explode("\r\n\r\n", $response, 2);

   return $response;
}

Thursday, February 09, 2012

Click and drag on a DOS prompt to pause the process

I always found this annoying, up until today. If you are running a process in a DOS box (like a server), clicking and dragging (to select text) will immediately pause the process. This caused trouble for me once years ago when I accidentally did this and couldn't work out why the server wasn't responding. Today I actually found a use for it.

I needed to debug an error in my Java web application that was happening during the application initialisation. Using Eclipse, I attach a remote debugger to the server, but the timing was hard, because the exception happens so quickly after I start the server. So, my solution: run the server from a DOS box and as quickly as I can after running the start command, click and drag on the DOS box.. then I can run the debugger and attach it before the exception occurs!

Oracle and Eclipse: SID vs Service Name

Saw this in Eclipse when trying to connect to an Oracle database using Data Source Explorer.

ORA-12505, TNS:listener does not currently know of SID given in connect descriptor

Problem seems to be that when setting up my Oracle Thin driver properties, the SID really has to be a SID, when all I have is a Service Name. It means that the resulting DB URL is: jdbc:oracle:thin:@host:port:sid when it should be: jdbc:oracle:thin:@host:port/service-name.

The answer is to use a different option in Eclipse when setting up the driver. Window > Preferences > Data Management > Connectivity > Driver Definitions > choose "Other Driver" for Oracle instead of Oracle Thin Driver. This gives you the option of directly setting the Connection URL.