Friday, 23 March 2012

Resolving OutOfMemoryError: unable to create new native thread

(This was tested on Red Hat EL6 JDK 1.6.31 64-bit)

If you've ever come across this error, it can be very misleading.
Caused by: java.lang.OutOfMemoryError: unable to create new native thread
 at java.lang.Thread.start0(Native Method)
 at java.lang.Thread.start(Thread.java:640)

The common suggestion (as the error suggests) is a memory related problem. Some tips but ultimately unhelpful:
http://candrews.integralblue.com/2009/01/preventing-outofmemoryerror-native-thread/
http://www.caucho.com/resin-3.0/performance/jvm-tuning.xtp
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
The common theme amongst all of them is the stack size.

Came across this post with same test code:

http://www.odi.ch/weblog/posting.php?posting=411
However the tests were inconsistent, modified it to only go 50 calls deep. Modified code here.
We discovered that changing the options made very little difference to the maximum number of threads.

Originally we thought it was related to changing the linux option for hard/soft maximum number of files that we did the day before:
# vi /etc/security/limits.conf 
testuser soft nofile 4096
testuser hard nofile 10240
# ulimit -Hn
10240

However that didn't seem to be it.

Then we finally came across max process per user:
ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 515005
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 4096
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

Which is set to 1024 by default. So adding this to ~/.profile fixed it for us:
ulimit -u 4096

Friday, 6 January 2012

Bulk upload of maven artifacts to remote repo

If you have an artifact you want to upload to a remote repository (i.e. internal company repo) then you use the command:
mvn deploy:deploy-file -Durl=file://C:\m2-repo \
                       -DrepositoryId=some.id \
                       -Dfile=your-artifact-1.0.jar \
                       [-DpomFile=your-pom.xml] \


However if you have more than a few files and they're in a nested directory structure (like your local repo) then this is not the way to do it. There doesn't seem to be any tool for either maven or nexus to do this, so here's a quick and dirty way I hacked together:
/**
 * run as java Importer [dirtosearch]
 **/
public class Importer {
   private String directory;
   private final static String repositoryId = "repo1";
   private final static String url = "http://remoteserver/nexus/content/repositories/repo1/";
   private final static String mvn = "C:/java/apache-maven-3.0.3/bin/mvn.bat";

   /**
    * @param directory
    */
   public Importer(String directory) {
      super();
      this.directory = directory;
   }

   public static void main(String[] args) {
      Importer importer = new Importer(args[0]);
      importer.go();
   }

   private void go() {
      try {
         File dir = new File(directory);

         doDir(dir);
      }
      catch (Throwable e) {
         e.printStackTrace();
      }
   }

   private void doDir(File dir) throws IOException, InterruptedException {
      File[] listFiles = dir.listFiles(new PomFilter());
      if (listFiles != null) {
         for (File pom : listFiles) {
            doPom(pom);
         }
      }

      File[] listDirs = dir.listFiles(new DirFilter());
      if (listDirs != null) {
         for (File subdir : listDirs) {
            doDir(subdir);
         }
      }
   }

   private void doPom(File pom) throws IOException, InterruptedException {
      File base = pom.getParentFile();
      String fileName = pom.getName();
      String jarName = fileName.substring(0, fileName.length() - 3) + "jar";
      File jar = new File(base.getAbsolutePath() + "/" + jarName);

      String exec = mvn + " deploy:deploy-file -DrepositoryId=" + repositoryId + " -Durl=" + url;
      if (jar.exists()) {
         exec += " -Dfile=\"" + jar.getAbsolutePath() + "\"";
      }
      else {
         exec += " -Dfile=\"" + pom.getAbsolutePath() + "\"";
      }
      exec += " -DpomFile=\"" + pom.getAbsolutePath() + "\"";
      exec(exec);

   }

   private void exec(String exec) throws InterruptedException, IOException {
      System.out.println(exec);
      Process p = Runtime.getRuntime().exec(exec);
      String line;
      BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
      BufferedReader bre = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      while ((line = bri.readLine()) != null) {
         System.out.println(line);
      }
      bri.close();
      while ((line = bre.readLine()) != null) {
         System.out.println(line);
      }
      bre.close();
      p.waitFor();
      System.out.println("Done.");
   }

   private class PomFilter implements java.io.FileFilter {

      @Override
      public boolean accept(File pathname) {
         return pathname.getName().endsWith(".pom");
      }
   }

   private class DirFilter implements java.io.FileFilter {

      @Override
      public boolean accept(File pathname) {
         return pathname.isDirectory();
      }
   }
}

Wednesday, 11 May 2011

WAS SOAPFault causing throws a WebServicesFault

When returning a SOAPFault from a SOAP handler I saw this in Websphere Application Server's (6.1.0) console:
[11/05/11 18:20:51:654 EST] 00000047 WebServicesSe E com.ibm.ws.webservices.engine.transport.http.WebServicesServlet doPost WSWS3227E:  Error: Exception:
                                 WebServicesFault
 faultCode: 666
 faultString: myfaultstring
 faultActor: myhandler
 faultDetail: 

myfaultstring
 at com.ibm.ws.webservices.engine.xmlsoap.builders.WebServicesFaultProcessor.createFault(WebServicesFaultProcessor.java:420)
 at com.ibm.ws.webservices.engine.xmlsoap.SOAPFault.getFault(SOAPFault.java:615)
 at com.ibm.ws.webservices.engine.SOAPPart.getFault(SOAPPart.java:1097)
 at com.ibm.ws.webservices.engine.SOAPPart.getFault(SOAPPart.java:754)
 at com.ibm.ws.webservices.engine.Message.getFault(Message.java:935)
 ....
Or when throwing a custom SOAPFaultException:
[11/05/11 18:32:05:678 EST] 00000065 WebServicesSe E com.ibm.ws.webservices.engine.transport.http.WebServicesServlet doPost WSWS3227E:  Error: Exception:
                                 WebServicesFault
 faultCode: myWebServiceFunction
 faultString: my test
 faultActor: testActor
 faultDetail: 

my test
 at com.ibm.ws.webservices.engine.WebServicesFault.makeFault(WebServicesFault.java:189)
 at com.ibm.ws.webservices.engine.dispatchers.java.SessionDispatcher.invoke(SessionDispatcher.java:213)
 at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:248)
 ...

A SOAP fault is still returned to the client but you get a WebServicesFault exception on both ends. Digging into Websphere's with the help of a decompiler shows that this is caused simply by no fault detail being passed. Simply adding a fault detail with a text of "error" gets rid of this error.

Monday, 1 November 2010

Persisting ViewScoped beans across views in request

I came across this problem when trying to deal with view scoped beans that you want to reuse in a different view, i.e. after clicking next in a wizard like page.

This was originally Discussed Here (now removed since Oracle merged Sun's forums).

The View Scope
There is a a brief summary of it here: JSF 2.0 New Feature Preview Series (Part 5) EDR1 Potpourri.
Basically view scoped values are attached to the current viewId. Values for the view scoped variables are stored in the map returned by UIViewRoot.getViewMap(boolean). Which is great for when your accessing the same view. However, it is cleared when the view is changed (e.g. from a navigation result) FacesContext.setViewRoot(javax.faces.component.UIViewRoot)

However, the flash scope was designed seemingly to solve this very problem.

Using the Flash Scope
Here's a write up of the Understanding the JSF 2.0 Flash scope. There's also some caveats shown here: The benefits and pitfalls of @ViewScoped.
So the logical step is to try it, :
public String doIt() {
   FacesContext.getCurrentInstance().getExternalContext().getFlash().put("thisBean", this);   return "next";
}
However, after some poking around, I discovered you can't re-store in FlashScope as ManagedBeanELResolver is before ScopedAttributeELResolver in the expression language resolver chain. Meaning that if you have a view "view1" with bean name "viewScopeBean1" and want to use the exact same bean in "view2" with bean name "viewScopeBean2", you can't.
The most you can do is store whatever data you need in the flash scope, then in the @PostConstruct of the new bean, pull in the values you need. Not an elegant solution but I'm sure messing around with the ELResolver chain could also do it but then you run the risk of it breaking else where.

Tuesday, 12 October 2010

f:convertNumber parses to double not BigDecimal

The default behaviour of the f:convertNumber, implemented with NumberConverter, in converting a decimal String of "1.11", is to convert it to a double and then JSF converts that to a BigDecimal. Most of the time you won't notice this happening until you use CallableStatement.setBigDecimal to invoke a stored procedure. In MS SQL Server, you get the following error:
com.microsoft.sqlserver.jdbc.SQLServerException: Error converting data type nvarchar to decimal.
The cause of this is because inside the BigDecimal it stored "1100000000000000976996261670137755572795867919921875" as a result of converting the String to a double. This floating point error is the motivation for using BigDecimal in the first place. And of course because the SQL Server JDBC driver didn't know how to handle the BigDecimal properly.

Looking into ConvertNumber, it uses one of two converters (DecimalFormat or NumberFormat) depending on whether 'pattern' is used. In Java 5, they added setParseBigDecimal(boolean newValue) in order to yield the desired output.

You can't easily change the NumberConverter but you can very simply add your own. To do so, I grabbed the source of NumberConverter from Mojarra 2.0.2 and copied all of it into my own class: net.devgrok.BigDecimalConverter.
@FacesConverter(forClass = BigDecimal.class, value="bigdecimal")
public class BigDecimalConverter implements Converter, PartialStateHolder {

// ... existing code

  public Object getAsObject(FacesContext context, UIComponent component, String value) {

// ... existing code

      // Create and configure the parser to be used
      parser = getNumberFormat(locale);
      if (((pattern != null) && pattern.length() != 0) || "currency".equals(type))
      {
        configureCurrency(parser);
      }
      parser.setParseIntegerOnly(isIntegerOnly());
      boolean groupSepChanged = false;

      // BEGIN BigDecimal HACK
      if (parser instanceof DecimalFormat)
      {
        ((DecimalFormat) parser).setParseBigDecimal(true);
      }
      // END BigDecimal HACK
      
// ... existing code

  }

// ... existing code

}
Then just create a file META-INF/custom.taglib.xml:
<?xml version="1.0" encoding="UTF-8"?>

<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    version="2.0">

    <namespace>http://devgrok.net/facestags</namespace>

    <tag>
        <tag-name>convertBigDecimal</tag-name>
        <converter>
            <converter-id>bigdecimal</converter-id>
        </converter>
    </tag>

</facelet-taglib>

And to use:
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:fn="http://java.sun.com/jsp/jstl/functions"
  xmlns:c="http://java.sun.com/jsp/jstl/core"
  xmlns:dg="http://devgrok.net/facestags"
  >

  from goes here etc
  
  <h:inputText id="txtPrice" value="#{bean.item.price}">
    <dg:convertBigDecimal pattern="##0.00" />
  </h:inputText>
  
</ui:composition