ZEN AND THE ART OF DEBUGGING OFBIZ ================================== 1. How to Debug OFBIZ You should first become as familiar with OFBIZ as possible by studying the tutorials and the cookbooks for the tools. The cookbooks are especially important because they show many of the subtleties of the framework which may not be at first apprent but could cause problems. You should also become familiar with the underlying technologies such as Freemarker, Beanshell, and XML. You may also experience problems which are wholely unrelated to OFBIZ, such as those caused by your database or server, and those problems would have to be fixed separately. Then, you should look through the log files carefully for the possible causes of your error. OFBIZ provides an enormous amount of information in the log files, so the trick is finding which one applies to the problem you are experiencing. This is more of an art than a science. What seems to work for us is to look for something in particular, such as something related to the application you are working on or a change that you may have made, and see if you can find it in the log file. If you really cannot find anything useful in the log file, then add your own logging messages until you have enough information to figure out what is going on. This guide will show you how the log files in OFBIZ work, how to add your own logging, and what some common messages mean. It will assume that you understand Java and the other related technologies, so the focus will be on issues and messages unique to OFBIZ. 2. The OFBIZ Log Files OFBIZ creates several log files and stores them all in the logs/ directory (opentaps-0.9 and prior versions) or framework/logs/ directory (post opentaps-0.9) The files are: - ofbiz.log.? - All logging messages generated by OFBIZ. This is cycled through, so ofbiz.log is most recent, ofbiz.log.1 is older, and ofbiz.log.2 is older than ofbiz.log.1 - console.log - A dump of everything that should be shown on the console while OFBIZ is running. May not be available. - access_log.? - A log file similar to the Apache httpd logs in format and shows the requests to the server. Cute but not useful for debugging. Most of the time, you will be looking at either ofbiz.log or console.log. Since there is so much content, you should open them in an editor so you can page through or search the logs. 3. Finding Log Messages Java log messages are the easiest to find. They will have the name of the class and the line number where the log message is generated: 111770[PaymentGatewayServices.java:776:INFO ] (Capture) Invoice [#10110] total: 38.54 Minilang methods will all show Log.java as the name of the class, such as this: 112499[ Log.java:103:INFO ] Finished quickShipEntireOrder:\nshipmentShipGroupFacilityList=[[shipmentId=10120, facilityId=WebStoreWarehouse, shipGroupSeqId=00001]]\nsuccessMessageList=[Created shipment with ID [10120] for ship group ID [00001] for facility ID [WebStoreWarehouse]] If you use the print directive in beanshell, the content of your print will just show up like this in the middle of the log file: 2006-07-19 13:46:26,373 [ ServiceDispatcher.java:450:DEBUG] [[Sync service finished- total:0.027,since last(Begin):0.027]] - 'ecommerce / getProductCategoryAndLimitedMembers' parentCategory = TABLE-LINENS-SOLIDS 2006-07-19 13:46:26,874 [ PriceServices.java:802:INFO ] PromoPrice and ProductPriceAction had null amount and no default price was available, using list price: 2.0 for product with id 15899 If you use Debug methods in beanshell, you will get something like this: 2006-07-19 13:46:26,373 [ ?:?] parentCategory = TABLE-LINENS-SOLIDS You may want to add your own information about where the log message is coming from if you cannot find your minilang or beanshell log messages. Everything generated by freemarker, screen-widget, or form widget will show up directly on your browser screen. There is nothing to look for in the logs unless those tools crashed. 4. Adding Your Own Logging Messages To add your own logging messages in Java, use one of the OFBIZ Debug methods (org.ofbiz.base.util.Debug), such as logInfo, logWarning, logError, etc.: Debug.logInfo("Now processing invoice " + invoiceId, module); module is a String which is usually the name of the class and is set in most OFBIZ Java classes at the top as a static. To add a logging message in beanshell, use the same Debug method, but pass a String such as "" in place of module. To add a logging message in freemarker, just display the variable you are trying to track, such as: ${invoice} <#-- will display the entire GenericValue invoice --> ${invoice.invoiceId} <#-- will display the invoiceId field of invoice --> To add a logging message in minilang, use the directive and write out your value like you would in freemarker: where level is used to set the level of logging, such as "info", "warning", "error", matching the Debug methods. 5. When You Need to Restart OFBIZ You will need to restart OFBIZ server if you have changed any of the following: - a Java file (don't forget to re-compile!) - a config/ .properties file - an entitymodel or entitygroup XML definition file - a services or secas XML file - a JPublish XML file You do not need to restart the OFBIZ server if you have modified: - a freemarker FTL template - a beanshell BSH template - a Screens XML file - a Forms XML file - the controller XML file (Note: on opentaps-0.8 and OFBIZ 3.x or earlier versions, you will have to re-start if you modify the controller) However, these files may require that you clear the cache in Web Tools > Cache Maintenance. 6. Common Errors and What They Mean: Cannot locate service by name (captureBillingAccountPayment) * The service (captureBillingAccountPayment) was not found in any services.xml definition found. Cannot find service location (org.ofbiz.order.order.OrderServices) * This means that the services XML definition points to a resource which does not exist. If it is a minilang or beanshell service, then the service engine could not locate the file. If it is a Java service, then the class was not found in any jar file in the path. Make sure that the file is where it's supposed to be, that your Java classes have been compiled, and that your ofbiz-component XML points to the file. Service method does not exist (com.opensourcestrategies.financials.invoice.InvoiceServices.setInvoiceDueDate(org.ofbiz.service.DispatchContext, java.util.Map)) * This means that this particular service has been defined in a services.xml, but the Java method it refers to could not be found. Usually this happens because it was not compiled. If you've recently updated please use $ ant to compile again. java.lang.IllegalArgumentException: Could not get next sequenced ID for sequence name: Party (Could not get next sequenced ID for sequence name: Party). * System could not get the next automatic ID for the entity, in this case Party. Usually a result of database disconnection. ERROR: insert or update on table "inventory_item" violates foreign key constraint "inv_item_facility" * Foreign key constraint violations are common problems that happen when you try to set the value of a field to something which it cannot be set to, because it is constrained by a foreign key to be only a value of another entity (table). For example, in this case, I tried to insert an InventoryItem entity with a facilityId which did not exist in the Facility entity, so the "inv_item_facility" key was violated. To fix these problems, look for the constraint (inv_item_facility in this case) in your entitymodel XML files, identify which entity and which field caused the problem, and make sure that your input is valid or that your code is correct. Error calling event: org.ofbiz.webapp.event.EventHandlerException: Service invocation error (Commit transaction failed) * This is a very nasty error message. What it actually means is that you called a service which then triggered some other services down the line through an ECA workflow, one of which has failed, thus causing your entire change of services to fail. The problem is that the service engine cannot track down the error for you, so you have to go through the log file and find it yourself. Go to your logs/ofbiz.log or logs/console.log and find the first error message after your request began (it could be quite a ways down), and that will be the one responsible for the problem. Unable to bind UserTransaction/TransactionManager to JNDI * This is a potential bug from the opentaps 0.8 and 0.9 and pre-Geronimo versions of OFBiz which could happen on Linux. The solution may be found here: http://lists.ofbiz.org/pipermail/users/2004-June/004094.html Message: The entity name must immediately follow the '&' in the entity reference. org.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference. * This is an XSL:FO error and means that you had the character '&' in your text, probably because it's part a description or address field. XSL:FO must be properly formatted as xml, so make sure you put ?xml after all the text fields.