Thursday, November 26, 2015

Find all Java classes implementing a given interface.... reflections!

https://code.google.com/p/reflections/

Download the ÜBER JAR here https://code.google.com/p/reflections/downloads/detail?name=reflections-0.9.9-RC1-uberjar.jar&can=2&q=


package pierre.reflections;
import java.net.URL;
import java.util.Set;

import org.reflections.Reflections;



public class FindInterfaceImplementations {
 public static void main(String[] args) {
  Reflections reflections = new Reflections();
  Set<URL> urls = reflections.getConfiguration().getUrls();
  for (URL item : urls) {
   System.out.println(item.toString());
  }
  Set<Class<? extends javax.enterprise.inject.spi.InjectionTargetFactory>> classes = reflections.getSubTypesOf(javax.enterprise.inject.spi.InjectionTargetFactory.class);
  System.out.println(classes.size());
 }

}



This version will load only classes under the "oracle" package:



package com.pierre.typequerylanguage;

import java.io.File;
import java.util.Set;

import org.reflections.Reflections;

import oracle.ucp.ConnectionAffinityCallback;

public class FindInterfaceImplementation {
 public static boolean VERBOSE = true;

 public static void main(String[] args) {
  if (VERBOSE) {
   System.out.println("searching in the following jars:");
   System.out.println(System.getProperty("java.class.path").replace(File.pathSeparatorChar, '\n'));
  }
  Reflections reflections = new Reflections("oracle");
  System.out.println("searching now");
  
  
  Set<Class<? extends ConnectionAffinityCallback>> classes = reflections.getSubTypesOf(oracle.ucp.ConnectionAffinityCallback.class);
  for (Class clazz : classes) {
   System.out.println("found: " + clazz.getCanonicalName());
  }
  System.out.println("searching done");
 }

}





Sunday, November 15, 2015

WLS 12.2.1 QUICK installer ignores response file

I was trying to install fmw_12.2.1.0.0_wls_quick.jar using the usual command line:
/usr/java/jdk1.8.0_65/bin/java -jar /opt/install/fmw_12.2.1.0.0_wls_quick.jar -silent -logLevel finest -debug -responseFile /opt/install/installfmw1221.rsp -invPtrLoc /etc/oraInst.loc
in vain... it would keep saying "Oracle Home not found, using default /tmp/hsperfdata_wls122/wls1221 " even if there is a variable ORACLE_HOME=/opt/oracle/fmw1221 in my response file.

Then I run "/usr/java/jdk1.8.0_65/bin/java -jar /opt/install/fmw_12.2.1.0.0_wls_quick.jar –help" and I my attention is drawn on this statement:
-responseFile   
        Location of the response file containing input for OUI. Ignored by quick installers.



So... the right syntax for QUICK installer is:

/usr/java/jdk1.8.0_65/bin/java -jar /opt/install/fmw_12.2.1.0.0_wls_quick.jar -silent -logLevel finest -debug ORACLE_HOME=/opt/oracle/fmw1221 -invPtrLoc /etc/oraInst.loc



Thursday, November 12, 2015

SCAN and REDIRECT with Oracle RAC

If you access a ORACLE RAC, be aware that you must open a firewall rule not only for the SCAN listener, but also to all the RAC instances. Connections are NOT routed via the SCAN listeners, they are merely client-side redirected.

Failure to do so will result in the connection fail with a Socket Timeout Exception. You will be puzzled because the telnet to the listener works... the problem is that your JDBC driver is trying to connect ALSO to the instance on a different IP (possibly also PORT...).... so you should test with telnet also the RAC instance!

import java.sql.DriverManager;
import java.sql.SQLException;

public class DBPing {
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                System.out.println("length " + args.length);
                String user = args[0];
                String password = args[1];
                String url = args[2];
                String now = new java.util.Date().toString();
                System.out.println(now + " user= " + user + " password=" + password + " url=" + url);
                java.sql.Connection conn = DriverManager.getConnection(url, user, password);
                System.out.println("ok");
        }
}


java -cp /acme/appsrv/bin/wl12.1a/oracle_common/modules/oracle.jdbc_12.1.0/ojdbc6.jar:/home/userpippo DBPing dbusername dbpassword "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=dbhostname-scan)(PORT=1522))(CONNECT_DATA=(SERVICE_NAME=myservicename)))" &^

The program will wait for connection for a while, then timeout. If you netstat BEFORE the timeout:

netstat -an | grep 1522

you will discover which IP corresponds to the RAC INSTANCE:

tcp 0 1 10.11.12.13:59482 44.55.66.222:1522 SYN_SENT

What is 44.55.66.222 ? It's NOT the dbhostname-scan IP, but rather the IP of a RAC instance.... the SCAN listener tells the Oracle JDBC driver to do a redirect to a new IP/PORT where the RAC instance is running.

What is SYN_SENT ? http://serverfault.com/questions/328361/tcptrack-shows-syn-sent-connections-does-that-mean-the-syn-package-reached-the .... which means that the JDBC driver sent a SYN, but the server didn't reply (because the firewall blocked the communication).

Here some doc on SCAN.
See also Oracle Support note "Port 1521 Open on Firewall But Unable to Connect Due to Errors: ORA-12535,TNS-12203 (Doc ID 361284.1)"


Sunday, November 8, 2015

JMC: how to capture details of caught and unlogged exceptions

It happens occasionally that inexperienced programmers catch an exception and ignore it, or they catch it and throw another exception without reporting the full details of the root cause.

This situation turns naturally in an operational nightmare.

But Java Mission Control can really help you out. Let´s run this code (remember the -XX:+UnlockCommercialFeatures -XX:+FlightRecorder ) :
public class ThrowsException {
 public static void main(String[] args) {
  while (true) {
   try {
    Thread.sleep(1000);
    throw new Exception("ciao bella gioia");
   }
   catch (Throwable t) {
   }
  }
 }
}


I run the JMC flight recorder, then go to the Code/Exceptions tab and this is what I get:



Saturday, November 7, 2015

Java Mission Control JMC with Java 7 u79

jmc is installed OOTB with this jmc.ini file:

-startup
../lib/missioncontrol/plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar
--launcher.library
../lib/missioncontrol/plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20141007-2033
--launcher.appendVmargs
-vm
../jre/bin/
-vmargs
-XX:+UseG1GC
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:FlightRecorderOptions=defaultrecording=true
-Djava.net.preferIPv4Stack=true


unfortunately it doesn't discover my local JVM (run with a JDK java!)

I get this error message:



"no local (attachable) JVM were detected". The JMC help says:
Why does Java Mission Control fail to find any local JVMs?
Consider the following:

•Make sure that you are using JAVA_HOME/bin/jmc to start the JMC client.


•If you are running JMC from Eclipse, make sure that Eclipse is running on a JDK (not JRE).


•Make sure that there is a directory named hsperfdata_username in the system's tmp directory, that it is writable by the user running JMC, and that the file system supports access control lists (ACLs).



First in the jmc.ini file I change ../jre/bin/ into C:\pierre\Java\jdk1.7.0_79\bin, then I select the C:\temp\hsperfdata_pierre folder and make it R/W (it was readonly!) and give full control to everyone. This time around all works fine. So sad that I don't get a better error message from JMC.... it would have been so simple just to display me a stacktrace or something more detailed. Even running "jmc -debug" didn't help...

If zou forget to run your program under test with the JMC options "-XX:+UnlockCommercialFeatures -XX:+FlightRecorder", you get this message:

Flight Recorder features are not enabled. To enable this you need to use a Java 7u4 or later JVM started with -XX:+UnlockCommercialFeatures -XX:+FlightRecorder.



Thursday, November 5, 2015

Limiting concurrent MDB pumping messages from a JMS (or MQ) queue (throttle)

you can use work managers with max-threads-constraint, or max-beans-in-free-pool : this is the ultimate source of truth... remember that by default you have only 16 concurrent beans registered as consumers on a queue:

https://docs.oracle.com/cd/E24329_01/web.1211/e24390/mdbtuning.htm#PERFM274



Sunday, November 1, 2015

JProfiler: Ingo Kegel man of the year

I was looking for training material on JProfiler and I found some 15 videos on youtube created by Ingo Kegel. He is really very professional! Thanks a lot Ingo! Ingo for President!


















Book: Pro JSF and HTML5



The book does a very good job at explaining the intricate history and structure of JSF framework, particularly regarding the CDI aspects. So definitely I would recommend it as an introduction to JSF.

However, I shake in terror at the idea of having to use JSF to develop font end application. The whole EL stuff reminds me of the days I have wasted trying to make JSTL tag library code work which fails silently... and JEE CDI seems to me another "magic under the hood" that becomes quite impossible to debug once anything goes wrong.

Besides, any attempt to write anything dynamic in a XML-like fashion should be straight away punished with 25 lashes on the back bottom. And any attempt to build complex expressions in a xhtml page using a combination of {, #, :, . , not validated by a compiler, is bound only to waste your life troubleshooting.

So, the learning curve is steep and the ways you can break the structure and waste days without any progress, infinite. It's a pity that frameworks like Vaadin don't get much attention and investment from big companies...

IMHO the root issue is that anybody with 2 hands and without at least a PhD in Mathematics can hack together a makeshift framework - glue, duct tape and some strings - and, if he hits the right market at the right time, find people who adopt it - for lack of a better alternative.