Thursday, September 23, 2010

NPE when configuring Subversion in JDeveloper

I haven't been using the SVN capabilities built in to JDeveloper for my local dev environment, but instead have been using Smart SVN (I'm on OS X, and wish I could Tortoise SVN). The trial version of Smart SVN does not enable some features, such as Branching and Tagging. I have a need to do this from my local machine and would prefer to do so in a GUI. Anwyay, I'm trying to do a check out from JDeveloper (11.1.1.1.0 Build JDEVADF_11.1.1.1.0_GENERIC_090615.0017.5407), and since I have not done so in this install of JDev, I have to first configure the SVN connection. Well, as soon as I click the 'Test Connection' button I get a Null Pointer Exception:

"Performing action Check Out...[ from oracle.ide.ceditor.CodeEditor ]
Invoking command: [ from oracle.ide.ceditor.CodeEditor ]
Uncaught exception
java.lang.NullPointerException
o.ji.vcs.svn.util.SVNRepositoryInfoValidator.validate(SVNRepositoryInfoValidator.java:58)
o.ji.vcs.svn.nav.ui.ConnectionPanel$ConnectionTesterThread.run(ConnectionPanel.java:412)


The solution is to remove/rename the existing preferences.xml (and possibly the repositories.xml) under the JDeveloper install directory:

%JDEV_HOME%/jdeveloper/system11.1.1.1.33.54.07/o.jdeveloper.subversion

Many Thanks to Nick for help on resolving this issue.

Wednesday, February 3, 2010

Running with Integrated WLS fails on Mac OS (8681385)

Loaded a different version of JDeveloper (Build JDEVADF_11.1.1.1.0_GENERIC_090615.0017.5407) today and ran into an issue that I knew I had seen before, which I think must have been cleared up with 11.1.1.2.0:

[08:26:20 AM] #### Deployment incomplete. ####
java.io.FileNotFoundException: /var/folders/fc/fcBxVMI8GS8ilNvLNsNQ6U TI/-Tmp-/adfmeta1829925691998595481.xml (No such file or directory)
at java.io.FileOutputStream.open(Native Method)


This is a known issue and is resolved by adding the following to the jdev.conf file:
AddVMOption -Djava.io.tmpdir=/var/tmp

Thursday, December 3, 2009

Session Level Shared AM is not what you think (or what the manual says!)

The JDeveloper manual gives the following definition for Session Level Shared Application Module:

If a view object instance queries data that depends on the current user, then the query can be cached at the session level and shared by all components that reference the row-set cache. For example, the session-level shared application module might contain a view instance with data security that takes a manager as the current user to return the list of direct reports. In this case, the cache of direct reports would exist for the duration of the manager's session.

After hours of failure, I found a discussion in the JDeveloper and ADF forum describing this issue.

In that post, Steve Muench offers the following explanation, (and subsequently has opened a bug on the Manual's faulted description):
The session scope shared application module is related to the ADFBC Session (SessionImpl) which cooperates with the Transaction object and is related to a single root application module. It is not shared across distinct root application modules. So, I don't believe that you're getting the sharing that you were expecting here.

The only thing that is shared across different root application modules would be an application-scope shared AM, or else something that the controller layer could make available like the HTTP Session, or one of the scopes like pageFlowScope which is managed distinctly from the number of root application modules used by the task flow.


Steve eventually points out that not all is lost trying to share view objects at a higher level than pageFlowScope:

If you can make the language a bind variable in the query, then you could use the application-shared AM. The shared rowsets are cached by unique bind variable combinations.

Since, I wanted to share my lookups for a given user based upon a given bind variable anyway, this will work just as I would like it to, and in fact slightly even better, because now it will be shared across all users, but still maintain a per user uniqueness. The manual describes how to do this pretty well, but you can ignore the other document bug (as pointed out in one of Avrom's Posts):

When viewing a data control usage from the DataBindings.cpx file in the Structure window, do not set the Configuration property to a shared application module configuration. By default, for an application module named AppModuleName, the Property Inspector will list the configurations named AppModuleNameShared and AppModuleNameLocal. At runtime, Oracle ADF uses the shared configuration automatically when you configure an application as a shared application module, but the configuration is not designed to be used by an application module data control usage

Go ahead and select the data control in question in the Structure Window for the DataBindings.cpx file and in the property inspector, set the configuration it should use to be the YourAppModuleShared configuration.

Tuesday, November 17, 2009

Referencing Bind Variables in Groovy

Thanks to Steve Muench for #143, 'Referencing UserData Map Values from View Object Bind Variables in Groovy' from Not Yet Documented ADF Sample Applications for help on figuring this one out.

I needed a ViewAccessor of my ViewObject to execute based upon a parameter calculated at run time. Generally, ViewAccessors, with required bind variables, are executed based upon an attribute in the main ViewObject, but in my case my ViewObject had no values for its attributes, because I was using it as a searchRegion (for the data binding of an af:query component) and although the I was setting the bind variable as the first step in my task-flow, the attribute on which I was trying to base the ViewAccessor's bind variable would always return null. So I created the following class that can be called via Groovy:

package com.mycompany.myproject.model.util;

import oracle.adf.model.bean.DCDataRow;

import oracle.jbo.ExprValueSupplier;
import oracle.jbo.JboReservedVarNames;
import oracle.jbo.Row;
import oracle.jbo.StructureDef;
import oracle.jbo.ViewObject;
import oracle.jbo.common.ViewCriteriaRowImpl;
import oracle.jbo.server.ViewRowImpl;

public class VOUtils {

public static Object bindValue(ViewObject vo, String bindName) {
return vo.getNamedWhereClauseParam(bindName);
}

/*
* Returns the value of the namedWhereClauseParam from the supplied VO.
* This was created so that bind variables values could be accessed via Groovy
*
* Groovy Example:
* com.synergetic.sis.model.util.VOUtils.bindValue(adf.object,"AgencyIdBind")
*
*/
public static Object bindValue(ExprValueSupplier valSupplier, String bindName) {
if (valSupplier instanceof Row) {
return bindValueFromRow((Row)valSupplier, bindName);
} else {
StructureDef sd =
(StructureDef)valSupplier.getExprVarVal(JboReservedVarNames.RESERVED_VAR_STRUCTURE_DEF);
if (sd instanceof ViewObject) {
return bindValue((ViewObject)sd, bindName);
} else if (sd instanceof Row) {
return bindValueFromRow((Row)sd, bindName);
} else {
System.out.println("Didn't handle case when valueSupplier was a " +
sd.getClass().getName());
}
}
return null;
}

public static Object bindValueFromRow(Row row, String bindName) {
ViewObject vo = null;
if (row instanceof DCDataRow) {
Object dp = ((DCDataRow)row).getDataProvider();
if (dp instanceof ViewCriteriaRowImpl) {
vo = ((ViewCriteriaRowImpl)dp).getViewCriteria().getViewObject();
}
} else {
vo = ((ViewRowImpl)row).getViewObject();
}
if (vo != null) {
return bindValue(vo, bindName);
}
return null;
}
}


This class can then be used to lookup the value of the ViewObject's bind variable using the following Groovy expression:
com.mycompany.myproject.model.util.VOUtils.bindValue(adf.object,"BindVariableName")

Wednesday, November 11, 2009

History Columns

When using the automatic audit feature of ADF's entity object, DO NOT check the Refresh After Insert or Refresh After Update checkboxes. These will prevent the columns from being updated with proper values.

Tuesday, April 21, 2009

Declarative Component, Custom Popup

I have incorporated all of the quirky requirements (for my project at least) for popups into a simple to use adf declarative component. This component is available to my entire project by means of an ADF Library JAR file (see how-to). It is included as a TagLib, which makes using it as simple as drag'n'drop. I include the lib as a JSP Tag Library whereas Frank does it a little bit different in the how-to.



You can download the whole project, AdfBitsComponent.zip or, if you want to just use the component library (as shown in the screen shot above), download just the jar AdfBitsComponentLib.jar.



    Features:
  1. Can be shown from javascript or java.

  2. Will ensure that no values are left over from the last time it was displayed (has been a major issue with our project).

  3. Has Save and Cancel buttons built in that call declared actions/actionListeners.

  4. Has optional confirmation prompt when using the cancel button (it will check to see if any of the editable values have changed, and if so will prompt the user to confirm, yes/no, that they want to cancel their edits).

  5. Will also capture the x, close-icon, and perform the Cancel button's actionListener, in case anything needs to be cleaned up once the popup is dismissed.

  6. Will click the Save button when the Enter key is pressed.

  7. Will click the Cancel button when the Escape key is pressed.

  8. If the Confirmation prompt is up, then pressing Enter will cause the current yes/no button to click.

  9. If the Confirmation prompt is up, then pressing Escape will cause the Confimration prompt to dismiss, but will allow the main popup to remain.

  10. All labels are customizable, but come with defaults set.

  11. Includes a facet to allow more buttons to be added between the Save and Cancel buttons.



If these features don't match your requirements (or if they don't work like you think they should), download the project and hack away at it.

Thursday, January 29, 2009

ERROR: Use of pinDataControl is not supported. Pinning the DataControl will result in severe performance issues.

This was discovered after implementing the code in the previous post on, "Hopping from one Train Stop to the next, causes the old stop to reexecute its bindings", although I do not believe it is directly related:


This was most likely in the console log all along, but only was noticed because of the fact that one of the executables, which was released after visiting a new tab, was being held onto and was trying to get reused. But since it had been released, it could no longer be used, and therefore threw up an exception, thus bringing the !ERROR! to our attention.

The FIX:
Reset the ChangeEventPolicy of the offending iterator back to the default, rather than "ppr".

According to the docs, ChangeEventPolicy can be used to perform automatic refresh of any UI component bound to the iterator when data is changed in the model and the docs actually recommend using it when there are a lot of components on a form that need ppr, however this was not needed in this particular case (and so far, nowhere else in our app).