Thursday, December 20, 2012

ADF: reminder new Entity Object - The specified schema object is not an existing object.

When creating a EO for the table accross schemas always prefix your schema object with the schema name:

ie common.table

It is not enough to select the Database Schema from the drop down

Thursday, December 13, 2012

Jdeveloper 11.1.1.6 upgrade integrated server to 10.3.6

NOTE: This may break some stuff so backup before you proceed so you have been warned

Prerequisites:
Install JDev 11.1.1.6
Run integrated weblogic.


Now install just weblogic 10.3.6 I used the generic installer.
java  -jar -D64 -Xmx1024M wls1036_generic.jar

Next > Select Create new MiddlewareHome and enter a value > Next > Typical > Next
Now select your JDK and click Next * 3

Run QuickStart

Click Next
Select 9.0 or Higher
Click Next

Find your integrated domain  [usually under C:\Users\[username]\AppData\Roaming\JDeveloper\system11.1.1.6.38.62.29\DefaultDomain]

NOTE: On windows I had to make this folder ! read only but this is not recommended. If you don't want to do this Install your integrated server in a different location

Click Next.


Once the Installer has finished backup setDomainEnv.cmd then copy setDomainEnv.cmd.back to setDomainEnv.cmd and edit the line:
set WL_HOME=... and make it set WL_HOME=C:\Dev\Oracle\Weblogic_10.3.6\wlserver_10.3

The location for these files is:
C:\Users\[user]\AppData\Roaming\JDeveloper\system11.1.1.6.38.62.29\DefaultDomain\bin

Wednesday, November 28, 2012

Back to blogging

After a little holiday and a change of continents I am back to blogging.

Hopefully I will have a few more Web Center and UCM posts also.

Sunday, September 30, 2012

ADF: forEach with showdetailheader

I had a showdetailheader inside a forEach which would just not disclose/ hide.

No matter what I tried the header would just not work.

So I changed the for each value from a binding to a get from the backing bean and everything worked as it should.

Strange...

Wednesday, September 19, 2012

ADF : Some solution to various UI related problems

11.1.1.5

So here is my handy list to myself of things to check if you are getting weird problems with things that should work (buttons not work, or drop downs misbehaving):

Mark you table as contentDelivery="immediate"
Remove partialSubmit="true" from some buttons
Remove immediate="true" from buttons
Use af:forEach instead of af:iterator.


Monday, September 10, 2012

Java: Generics dont keep it simple stupid

So I was playing around with generics (dont love them because of type erasure - class level is ok method level gets scary) the other day and here are some examples and lessons learned:

1) Method level generics with return types are harder than they look.
2) Wildcards and when to use them confuse me.
3) My code is ugly and I must be missing something but what - who knows.


What I wanted was a Singleton class with generic get and put methods (what you put in is what you get out) without the cast. Something that works a little like Collections.emptyList();


The map I was storing my generic stuff in  ignore the naming for now:

What I wanted to do is something like this:

CacheItem<AnItem>  someCacheItem  = new DateCacheItemImpl<AnItem>();

Cache.getInstance().register(NameCacheItem.class);
Cache.getInstance().put(someCacheItem);

CacheItem<AnotherItem>  anotherCacheItem  = Cache.getInstance().get();



private ConcurrentHashMap<String, CacheItem<? extends ParentItem>> cacheMap =
  new ConcurrentHashMap<String, CacheItem<? extends  Parent Item>>();

public <T extends CacheItem<? extends  ParentItem >> void put(T cacheInstance) {

    cacheMap.put(cacheInstance.getCacheKey(), cacheInstance);
}

public <T extends CacheItem<? extends  ParentItem>> T get(String cacheKey) {
    return (T)cacheMap.get(cacheKey);
}

    public <T extends CacheItem<? extends  ParentItem >> void registerCache(Class<T> clazz) {

        try {
            CacheItem<? extends  ParentItem  > cacheInstance = clazz.newInstance();
            put(cacheInstance);
        } catch (InstantiationException e) {
            LOGGER.warning("Unable to create cache " + clazz.getName());
        } catch (IllegalAccessException e) {
            LOGGER.warning("Unable to create cache " + clazz.getName());
        }
    }


Not exactly what I wanted, will update this post once I have a epiphany.

Monday, September 3, 2012

ADF: SelectOneChoice ForEach, Filter - Drop down list keeping the first size selected

Ok so I had a bunch of filters all rendered from a backing bean using the forEach tag to render the select items.

On updating the table the filters would always have the size of the initially selected item - not good.
So if you fist selection had one item in the filter the filter would always be one item big.

SOLUTION:
Changed from a forEach to a f:SelectItems creating the Select items in my backing bean - everything worked.

Nice and simple.


    public List<SelectItem> listUniqueSelectItemList(List<String> items) {
        List<SelectItem> itemList = new ArrayList<SelectItem>();
        if (items != null) {
            for (String item : items) {
                itemList.add(createSelectItem(item));
            }
        }
        return itemList;
    }

    private SelectItem createSelectItem(String filter) {
        return new SelectItem(filter, filter);
    }



                  <af:selectOneChoice value="#{pageFlowScope.testBean.stringFilterValue}"
                                      id="soc1"
                                      unselectedLabel="#{bundle['test.unselected.label']}"
                                      label="filter"
                                      autoSubmit="true">
                    <f:selectItems value="#{pageFlowScope.scheduleBean.listUniqueTestItems}"
                                id="fe_it"/>
                  </af:selectOneChoice>



Wednesday, August 22, 2012

ADF : task flow replace whole page not current region

Ok so this is one way to break out of the region you are in and replace a parent or root region.

So in your child task flow instead of calling a task flow directly using a control flow case just point your control flow case to a Parent Action (get it from the component panel). There you can specify an outcome in a parent task flow.

Job done.

Tuesday, August 21, 2012

Web Center ADF : What a dirty little problem MDS override customizations

I have a customizable table where you can save sort orders to the database (custom not mds driven - don't ask why - you don't want to know).

So everything works for me locally but upon deployment to Web Center once you have moved one column everything has that column order in the table no matter what until you close the browser and re login.

Not I have no MDS configured on my local box.

Turns out someone turned mds config on in my project properties thus rendering my custom ordering view useless because MDS would override my changes - so I turned MDS off in this project because I dont need it. I am not sure what you would do if you needed it on would need to customize it a bit I guess - not easy.

PAIN in the arse to figure this one out.

O yhea and dont think just clicking the MDS to off will remove your problem check the adf-config.xml to check if any elements have been hard set to persist.

Friday, August 17, 2012

Exception: NullPointerException java.util.ResourceBundle$CacheKey.calculateHashCode

I was missing the <message-bundle>com.test.view.props.test</message-bundle> entry in my faces-config.xml for some code that looked up a default message bundle in my faces application.


And I got a NullPointerException java.util.ResourceBundle$CacheKey.calculateHashCode
not really explanatory but hey well.
.

Monday, August 6, 2012

Java: On login trigger code run after login

Ok so from the title you can see I am hanging around the database for way to long.

I needed to have some code executed when I logged on so this is what I did:

I threw together a quick HttpSessionListener like such:

package za.co.test.web.faces.listener;

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class LoginSessionListener implements HttpSessionListener
{
 @Override
 public void sessionCreated(HttpSessionEvent event) {
 doSomeStuff();
 }

@Override
public void sessionDestroyed(HttpSessionEvent event)
{
// do nothing
}
}




Then added the listener to my web.xml.


<listener>
<listener-class>za.co.test.web.faces.listener.LoginSessionListener</listener-class>
</listener>



All working and sorted.

Wednesday, July 25, 2012

XSLT : Fun with xslt and xpath with fop

So I wanted a generic, all things to all men style sheet transformation on my service call to generate a PDF report for any xml message.

I had to do this using XSLT 1.0 booo hiss. This really make things harder. So here is what I learned:

So the first thing I needed was a JAXB transform from incoming object to xml.


        JAXBContext context = JAXBContext.newInstance(xmlObject.getClass());
        Marshaller marshaller = context.createMarshaller();
        StringWriter sw = new StringWriter();
        marshaller.marshal(xmlObject, sw);
        IOUtils.closeQuietly(sw);
        return sw.toString();



The next thing was passing parameters (a report title)


            Transformer transformer = tFactory.newTransformer(xsltSrc);
            transformer.setParameter("ReportTitle", "Report Title");

<xsl:param name="ReportTitle" select="'None'"/>
<xsl:value-of select="$ReportTitle"/>


Making the element tag names human readable


  <xsl:template name="ConvertToReadable">
    <xsl:param name="text"/>
    <xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
    <xsl:if test="$text != ''">
      <xsl:variable name="letter" select="substring($text, 1, 1)"/>
      <xsl:choose>
        <xsl:when test="contains($vUpper, $letter)">
          <xsl:value-of select="concat(' ', $letter)"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="$letter"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:call-template name="ConvertToReadable">
        <xsl:with-param name="text" select="substring-after($text, $letter)"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>




Formatting and checking dates : this was a little tricky I had to use EXSLT (which is included if you use xalan) add the following namespace : xmlns:datetime="http://exslt.org/dates-and-times" and


 <xsl:when test="datetime:date(.) != ''">
   <xsl:value-of select="datetime:format-date(., 'yyyy/MM/dd HH:mm')"/>
 </xsl:when>


Formatting and checking numbers:

<xsl:when test="number(.) = .">
  <xsl:value-of select="format-number(., '#######.#####')"/>
</xsl:when>


Friday, June 29, 2012

My Pentaho experience

I was playing with pentaho over the weekend and must say I am impressed with what I have seen.

The report designer is now very functional. I am going to have to play with it a bit more to be understand what can be done fully but producing a report with parameters is really easy once you get a hang of the tool.
(I click on the query you want to modify and modify the sql instead of using the edit button)

I replaced the pentaho security implementation with my own implementation and was surprised to find out how easy the spring security implementation was (one thing I wrote my own GrantedAuthority implementation which was a bad idea the default one org.springframework.security.GrantedAuthorityImpl works well and includes an equals, hashcode and compareto which mine did not and didnt work and implementation) 

Monday, June 11, 2012

ADF: Testing iterator settings Pojo Data Controls

Jdev 11.1.1.5


I was doing some investigation into the inner workings and some of the more useful properties on the iterator bindings in the page definition xml files to to satisfy my curiosity.

So here are some findings I have to go into much more details than this but this should help someone.

I had a basic page with one iterator (driving a select one choice) two buttons one with an action one with an action listener and a child iterator driving a table.

I use any number of Refresh parameters on my page (always, deferred, ifNeeded) etc and the method bound was only called once on pressing any button or autoSubmit - all good.

I the set the CacheResults parameter to false this lead to my method being called a number of times and some weird but expected behaviour still good.

Now I changed to a methodIterator from a accessorIterator with one parameter and returned null from the data control. The method was now called a number of times with a null parameter not good. I changed the return null to return an empty list and everything started working as expected.

Need to still check immediate, partialSubmit, changeEventPolicy and a few other attributes but this answered some of my questions.

Eclipse maven problems m2e


Project configuration is not up-to-date with pom.xml
Right click project, select Maven, click Update Project configuration

Plugin execution not covered by lifecycle configuration
Click on the error nice red error (in the pom.xml Overview tab)
Select the permanently mark goal as ignore, click ok

Sorted

Derby, glassfish startup scripts


Startup script for my glassfish:
call asadmin start-database --dbhost 0.0.0.0 --dbport 1527
call asadmin start-domain domain1

Stop script for my glassfish

call asadmin stop-database
call asadmin stop-domain domain1

Derby current time in sql
CURRENT_TIMESTAMP

Thursday, May 24, 2012

ADF Table dependant list select one choice : Thing I learned being stupid final

It ended up the source of all my problems was an invalid long to string conversion while rendering my select items.

So if you are having endless hassles with a dependent select box in a table try this when you are rendering the lists to make sure you are not rendering a string and matching on long or int:
    public List convertItem(List dataItems) {
        ArrayList covertedList = new ArrayList();
        if (dataItems != null) {
            for (Site dataItem : dataItems) {
                SelectItem item = new SelectItem(new String(dataItem.getId()), dataItem.getDescription());
                covertedList.add(item);
            }

        }
        return covertedList;
    }

ADF forEach : Things I learned being stupid 3

The el lookup of #{row} will not work in a for each period - dont torture yourself.

Wednesday, May 23, 2012

ADF Dependant select items in a table: Things I learned being stupid


Hard hard thing to do - table of dependant select items that you can add new rows to. (backing bean driven)
(When you add a new row it keeps values from the previous row)

In my search for the answer I made an forEach act like a table - by using the f:attribute to pass through the current row - crazy but I hopw this helps someone sometime.

Stuff I learned
            <af:selectOneChoice label="#{labelBundle['choice_lbl']}"
                                id="soc1" value="#{row.choiceId}"
                                valueChangeListener="#{pageFlowScope.testBean.choiceValueChange}"
                                required="true"
                                autoSubmit="true" unselectedLabel="Choose...">
              <f:attribute name="currentRow" value="#{row}"/>
              <f:selectItems id="isItem" value="#{row.choiceList}"/>
            </af:selectOneChoice>

Notice the f:attribute - this can pass any value to the backing bean in this case the row. - very bad for performance though.

Refresh on the component you need on value change:
in your value change listener : refreshDependantComponent("soc 2", valueChangeEvent.getComponent());



    private void refreshDependantComponent(String idMatch, UIComponent uiComponent) {
        UIComponent parent = uiComponent.getParent();
        Iterator iter = parent.getFacetsAndChildren();
        while (iter.hasNext()) {
            UIComponent iterItem = iter.next();
            if (iterItem.getId() != null && iterItem.getId().startsWith(idMatch)) {
                AdfFacesContext.getCurrentInstance().addPartialTarget(iterItem);
            }
        }
    }


Real solutions: : http://itnewscast.com/applications/how-populate-different-select-list-content-table-row
Or dont use immediate="true"

Thanks Jeromy for sending this to me and thanks Frank for the post.

ADF Defaulting a backing bean driven select: Thing I learned being stupid 1

Jdeveloper 11.1.1.5

Ok,

I had a selectonechoice that was driven by a pojo data control and I just couldn't get its value defaulted.
The following is what I learned along the way and my unique solution:

Drag and drop the item onto the page as a single choice selectonechoice:
Add a variable to your page binding (open your page and click on the bindings tab - right click on variables under Executables - insert inside variables - select variable - Name:selectedItemValue Type: java.lang.Object

Then click on Page definition file and update the variable you just added and add these attributes DefaultValue="#{pageFlowScope.TestBean.id}" IsUpdateable="2".
NOTE: the bold bit pageFlowScope.TestBean.id must be the value you want to default to.

Or you can just paste the xml like such:



<variable Type="java.lang.Integer" Name="selectedItemValue" DefaultValue="#{pageFlowScope.TestBean.id}" IsUpdateable="2" />


Then update your list binding to something like this (you can get this done using the green plus button but I am too lazy to post how if you need to know ask):


    <list StaticList="false" IterBinding="variables"
          ListIter="listItemsIterator" NullValueFlag="start" id="selectedItemValueList">
      <AttrNames>
        <Item Value="selectedItemValue"/>
      </AttrNames>
      <ListAttrNames>
        <Item Value="id"/>
      </ListAttrNames>
      <ListDisplayAttrNames>
        <<tem Value="name"/>
      </ListDisplayAttrNames>
    </list>

NullValueFlag="start" - gives you an empty item

This be my select one choice.
          <af:selectOneChoice value="#{bindings.selectedItemValueList.inputValue}"
                              label="#{bindings.selectedItemValueList.label}"
                              id="soc1"
                              valuePassThru="true" autoSubmit="true"
                              clientComponent="true">
            <f:selectItems value="#{bindings.selectedItemValueList.items}" id="siI"/>
          </af:selectOneChoice>



Handy helpful EL:

1) #{bindings.selectedItemValueList.attribute} - this will give you the actual id of the select box selected item
2) #{bindings.selectedItemValueList.inputValue} = this will give you the index 0 based of the selected item
3) #{bindings.selectedItemValueList.selectedValue == null ? null : bindings.selectedItemValueList.selectedValue.dataProvider} - this gives you the actual underlying object used so you can get the label from here.

Save Button
The save button I use because I need the object not just the object id



            <af:setPropertyListener from="#{bindings.selectedItemValueList.selectedValue == null ? null : bindings. selectedItemValueList .selectedValue.dataProvider}"
                                    to="#{pageFlowScope.listBean.currentValue.selectedItem}"
                                    type="action"/>
          </af:commandButton>




Random code

        Object expr = JsfUtil.resolveELExpression("#{bindings.selectedItemValueList}");
        if (expr instanceof FacesCtrlListBinding) {
            FacesCtrlListBinding list = (FacesCtrlListBinding)expr;
            UIComponent component = valueChangeEvent.getComponent();
            component.processUpdates(FacesContext.getCurrentInstance()); //do model updates for this comp
            DCDataRow row = (DCDataRow)list.getSelectedValue();
            ListItem i = (ListItem)().getDataProvider(); // get actual object via code
        }


Note
Create a list and change the binding xml for your list (ListOperMode attribute) from navigation to  setAttribute and see hoe things change

Tuesday, May 8, 2012

SoapUI start mocks on project load

I wanted to find where you can set all your mocks to load on start up of your project:

1) Double click on your project
2) Click on the Load Script tab
3) Place the below script in the Script section.

Press the play button to test





 The Script
for( ms in project.mockServiceList )
{
    // open window
    def dp = com.eviware.soapui.support.UISupport.showDesktopPanel( ms )

    // start mockservice
    ms.start()

    // minimize window
    com.eviware.soapui.SoapUI.desktop.minimize( dp )
}


Information found at soap ui forum:
http://www.soapui.org/forum/viewtopic.php?f=5&t=1138

ANT Jdeveloper what it really calls

I was wondering what Jdeveloper did in the background while running ant because I wanted to replicate exactly what was happening in JDev.

So I set the ant run task to debug and passed in an invalid argument ant the following was the output:

java -Djavax.xml.transform.TransformerFactory=com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -classpath %ORACLE_HOME%\jdeveloper\jdev\lib\ojc.jar;%ORACLE_HOME%\jdeveloper\jdev\lib\ant-rt.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-antlr.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-apache-bcel.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-apache-bsf.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-apache-log4j.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-apache-oro.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-apache-regexp.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-apache-resolver.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-commons-logging.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-commons-net.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-jai.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-javamail.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-jdepend.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-jmf.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-jsch.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-junit.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-launcher.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-netrexx.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-nodeps.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-starteam.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-stylebook.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-swing.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-testutil.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-trax.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant-weblogic.jar;%ORACLE_HOME%\jdeveloper\ant\lib\ant.jar;%ORACLE_HOME%\jdeveloper\ant\lib\junit.jar;%ORACLE_HOME%\jdeveloper\ant\lib\xercesImpl.jar;%ORACLE_HOME%\jdeveloper\ant\lib\xml-apis.jar;%ORACLE_HOME%\jdk160_24\lib\tools.jar -Djdev.ant.port=54325 -Dant.home=%ORACLE_HOME%\jdeveloper\ant -XX:MaxPermSize=512M org.apache.tools.ant.Main -inputhandler oracle.jdevimpl.ant.runner.OutOfProcessInputHandler -f c:\test\theBuild.xml -Doracle.home=%ORACLE_HOME%\jdeveloper\ -Doracle_wl_home=%ORACLE_HOME%\wlserver_10.3 buildAll

Thursday, May 3, 2012

Using Soap UI to test services

I needed to test a screen that was backed by services and it was suggested that I use soapUI.
I haven't used soapUI for a while now and was surprised to see mock service functionality.

Mock Service (http://www.soapui.org/Service-Mocking/concept.html)


So first take the wsdl you have and generate a mock service using soap ui.
Create a new project: File Menu > Create new soapUI project.
Select the wsdl you will be working with.



Right click on the new Binding and select Generate MockService
Press ok twice.



Right click on the new Mock and select Start minimized.

Ok I like using the Query Match functionality it just works for my brain:
You can create as many mock responses as you like and edit the xml response as you wish.

You the add Query matches for each of your responses based on data passed in.
The xpath bit is the matching rules
The expected value is the value to match on in the incoming message
Last dropdown is the response you choose to return based on the above input





Important Soapy Example match

declare namespace v1='http://test.co.za/stuff/Messages/Test/V1';
declare namespace soapenv='http://schemas.xmlsoap.org/soap/envelope/';
//soapenv:Envelope/soapenv:Body/v1:GetTests/v1:TestId


Make sure the mock service is running.

Hook up to code
Now point your code (web service proxy pojo data control for me) to use the mock service url.

Example:


new TestService(new URL("http://127.0.0.1:8088/mockTestService", new QName("http://www.test.co.za/Test/V1","TestService")));


Run screen and test away.

http://www.soapui.org/

I am using 4.5.0

Wednesday, April 18, 2012

ADF: Eclipse plugin

http://marketplace.eclipse.org/content/oracle-enterprise-pack-eclipse

Anybody given this a try would really like to know if it works.
 Will be giving it a look soon and will post comment here.

Friday, April 13, 2012

ADF : Pojo Data Control : structure definition does not have a primary key attribute

I had a minor difficulty with creating a POJO data control today.

The create data control failed with the following error: structure definition does not have a primary key attribute
Fixed the package problem (DC java file resided in a package different from what was specified in the package section inside the java class)

Not a very clear error indeed, note to self don't make stupid errors.

Monday, March 26, 2012

ADF: debugging taskflows

I was having huge hassles with my task flow rerouting to themselves. I am using routers and pageflow scope varibles across bounded task flows. Mainly failed on task flow return items that went by default to a router.


This post saved my bacon : http://biemond.blogspot.com/2008/10/debugging-task-flow-in-jdeveloper-11g.html

Before and after listeners in your task-flow-call are also helpful for debugging:
<before-listener>#{viewScope.chargeOutsEditBean.afterListener}</before-listener>
<after-listener>#{viewScope.chargeOutsEditBean.afterListener}</after-listener>


  public String beforeListener() {
    System.out.println("beforeListener() {");
    System.out.println("--------------------------->route Before:" + ADFContext.getCurrent().getPageFlowScope().get("route"));
    return "blist";
  }


  public String afterListener() {
    System.out.println("afterListener() {");
    System.out.println("--------------------------->route After:" + ADFContext.getCurrent().getPageFlowScope().get("route"));
    return "list";
  }

ADF odd error : ADFC-10001: cannot instantiate class

Running one of my adf pages with some code in the construtor O got the following error:

JspServlet error: Servlet unable to dispatch to the following requested page: The following exception occurred:javax.faces.FacesException: javax.faces.FacesException: oracle.adf.controller.ControllerException:
ADFC-10001: cannot instantiate class 'za.co.test.adf.ops.view.common.form.TestBean'

I was adding a partial target to my page in the constructor which is a no no - remove the line
AdfFacesContext.getCurrentInstance().addPartialTarget(getResultTable()); and all was well again.

Note: this can also be caused by any error in the bean constructor.

Friday, March 16, 2012

Java basic encryption decrypt util


Because I always need to do this for passwords in files and various utilities I thought I would post the code.

Note: it is more secure to encrypt one way (cryptographic hashing) this is for simple no hassle cases.



package za.co.test.common.util;



import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;


public class EncryptionUtil {
private static final byte[] SECRET_KEY = "TESTKEY2013StormersRugby".getBytes();
    public static byte[] encryptToByteArray(String input)
        throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
        Key key = generateKey();
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] inputBytes = input.getBytes();
        inputBytes = cipher.doFinal(inputBytes);
        return Base64.encodeBase64(inputBytes);
    }

    public static String decryptByteArray(byte[] encryptionBytes)
        throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
        Key key = generateKey();
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] recoveredBytes = Base64.decodeBase64(encryptionBytes);
        recoveredBytes = cipher.doFinal(recoveredBytes);
        String recovered = new String(recoveredBytes);
        return recovered;
    }

    public static String encrypt(String input)
        throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException,
               UnsupportedEncodingException {
        byte[] inputBytes = encryptToByteArray(input);
        return new String(inputBytes);
    }

    public static String decrypt(String encryptionBytes)
        throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
        return decryptByteArray(encryptionBytes.getBytes());
    }

    private static Key generateKey() {
        Key key = new SecretKeySpec(SECRET_KEY, ALGORITHM);
        return key;
    }

    public static void main(String[] args)
        throws Exception {
        if (args == null || args.length < 1 || args[0] == null || args[0].length() < 1) {
            throw new NullPointerException("Please enter a password. Usage : java za.co.test.common.util.EncryptionUtil ");
        }
        String password = args[0];
        String pwd = EncryptionUtil.encrypt(password);
        System.out.println("The encrypted password is ---> " + pwd);
    }
}


Wednesday, March 14, 2012

ADF: PS_TXN unique constraint violated passivation

Ok so I had this problem in a few applications and want to solve it the best way once and for all.
java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (SCHEMA.PS_TXN_PK) violated or oracle.jbo.PCollException: JBO-28030: Could not insert row into table PS_TXN, collection id . What a pain.

So I have come across a couple of methods to solve this one:

1) Cleanup table regularly - this is a poor solution and is not guaranteed to work all the time. This involves creating a job to run (maybe twice a day) to sort the sequences out and clean up tables. Although it is the easiest to implement and requires no code changes. Can use this as a stop gap measure while your developers are fixing the real problem.

2) use a file store for passivation - better solution this one but I must test the performance impact and what to do if the filestore get corrupt. This involves setting the AM property  jbo.passivationstore = file on all Application Modules. Not convinced this is the best solution but it should do for small apps.

3) using one schema with jbo.server.internal_connection - just specify your datasource name in this property to point to a utility schema and you should be good to go.

4) Catching the error and doing a clean at this point - Lot of work this one better than solution 1 but really not a productive use of time. (I havent tried this one)

I really need to finish the performance testing on our current application with the 11.1.2.1 and unit test before I make the call.

http://www.oracle.com/technetwork/developer-tools/jdev/overview/bc4j-temp-tables-087270.html

Friday, March 9, 2012

Weblogic and ADF : migrateSecurityStore the hard way

I was struggeling to use WSLT to migrate my policy store for our production cluster there where classpath problems and naming problems and I just want to make the process easier for my self.

So I wrote a little util to do the migration if nothing else this post will help me remeber the classes needed for the migration exercise.

Script and classpath (I can post my linux script if anyone wants it)
My jar file that you wont have but I will post the code: common.0.0.1.jar, ./migrator.jar
Non adf etc 3rd party jars: ./lib/commons-cli-1.2.jar;./lib/commons-io-2.0.1.jar;

SET WEBLOGIC_JAR=[your Middleware location]\wlserver_10.3\server\lib\weblogic.jar
SET OLD_CLASSPATH=%CLASSPATH%
SET CLASSPATH=%CLASSPATH%;%WEBLOGIC_JAR%;./lib/adf-controller-security.jar;./migrator.jar;./lib/adf-share-mbeans-wlst.jar;./lib/adfscripting.jar;./lib/commons-cli-1.2.jar;./lib/commons-io-2.0.1.jar;./lib/commons-logging-1.1.1.jar;./lib/common.0.0.1.jar;./lib/ldapjclnt11.jar;./lib/adf-share-base.jar;./lib/adf-share-security.jar;./lib/adf-share-ca.jar;./lib/adfm.jar;./lib/oracle.webservices.standalone.client.jar

%JAVA_HOME%\bin\java za.co.test.adf.common.migrate.MigrationUtil -z C:\Dev\Middleware\user_projects\domains\dev_domain\config\fmwconfig\system-jazn-data.xml -e C:\Dev\wb-ops.0.0.1.ear

SET CLASSPATH=%OLD_CLASSPATH%

Scripts directory
In the directory I run the java from ./scripts I copyed all the .py files needed for my migrator to work.
These can be found in [your Middleware location]\oracle_common\modules\oracle.jps_11.1.1\common\wlstscripts

Migration parameters and what the class does


The migration class will take the location of a jazn-data.xml file OR an ear containing the jazn-data.xml create a temporary migration jps file call the python migration script and write the policies to your specified system-jazn-data.xml file.


-s or --src source policy config name : defaults appPolicy
-d or --dst destination policy config name : defaults domainPolicy
-c or --script Location of all the .py scripts to run wlst
-j or --jazn jazn file to import location
-z or sysjazn system jazn file to copy to full location
-e or --ear Ear file to extract jazn file from : cant be used with jazn");


typical usage is just to use -e ear location and the -z system-jazn location parameters.
 
Java code stuff


Note : 

You can replace the custom streamuilts stuff as follows:

String fileContent = StreamUtil.drainToString(new FileReader(DEFAULT_MIGRATION_SCRIPT_LOCATION));
with

String fileContent =  new String (IOUtils.toByteArray(new FileInputStream(DEFAULT_MIGRATION_SCRIPT_LOCATION)));

package za.co.test.adf.common.migrate;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;

import java.text.MessageFormat;

import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.IOUtils;

import org.python.util.InteractiveInterpreter;

import weblogic.management.scripting.utils.WLSTInterpreter;

import za.co.test.adf.common.util.StreamUtil;


public class MigrationUtil {
  static InteractiveInterpreter interpreter = null;
  private static final String DEFAULT_SCRIPT_LOCATION = "./scripts";
  private static final String DEFAULT_TMP_LOCATION = "./tmp";
  private static final String DEFAULT_WLST_SCRIPT_LOCATION
    = DEFAULT_SCRIPT_LOCATION + "/wlst";
  private static final String DEFAULT_MIGRATION_SCRIPT_LOCATION
    = DEFAULT_SCRIPT_LOCATION + "/migrate-jps-config.xml";
  private static final String DEFAULT_JAZN_SUFFIX = "/jazn-data.xml";
  private static final String SOURCE_OPTION_NAME = "s";
  private static final String DESTINATION_OPTION_NAME = "d";
  private static final String JAZN_OPTION_NAME = "j";
  private static final String SYSJAZN_OPTION_NAME = "z";
  private static final String EAR_OPTION_NAME = "e";
  private static final String SCRIPT_OPTION_NAME = "c";
  public MigrationUtil() {
    super();
  }

  public static void main(String[] args) throws IOException, ParseException {
    String scriptLocation = DEFAULT_WLST_SCRIPT_LOCATION;
    String source = "appPolicy";
    String destination = "domainPolicy";
    String jaznFile = null;
    String systemJaznLocation = null;
    String migrationFileEar = null;

    args = new String[] { "--sysjazn", "C:/Dev/Middleware/user_projects/domains"
      +"/dev_domain/config/fmwconfig/system-jazn-data.xml", "-e",
      "C:\\Dev\\Projects\\WesbankADF\\deploy\\wb-home.0.0.1.ear"};
    CommandLineParser parser = new PosixParser();
    Options options = createOptions();
    CommandLine cmd = parser.parse(options, args);
    if(cmd.hasOption(SOURCE_OPTION_NAME)) {
      source = cmd.getOptionValue(SOURCE_OPTION_NAME);
    }
    if(cmd.hasOption(DESTINATION_OPTION_NAME)) {
      destination = cmd.getOptionValue(DESTINATION_OPTION_NAME);
    }
    if(cmd.hasOption(SCRIPT_OPTION_NAME)) {
      scriptLocation = cmd.getOptionValue(SCRIPT_OPTION_NAME);
    }
    if(cmd.hasOption(JAZN_OPTION_NAME)) {
      jaznFile = cmd.getOptionValue(JAZN_OPTION_NAME);
    }
    if(cmd.hasOption(EAR_OPTION_NAME)) {
      migrationFileEar = cmd.getOptionValue(EAR_OPTION_NAME);
    }
    if((jaznFile == null || jaznFile.length() < 1) &&
     (migrationFileEar == null || migrationFileEar.length() < 1)) {
      throw new ParseException(
        "Either ear option name (-e) or jazn file name (-j) must be populated");
    }

    if(cmd.hasOption(SYSJAZN_OPTION_NAME)) {
      systemJaznLocation = cmd.getOptionValue(SYSJAZN_OPTION_NAME);
    }

    systemJaznLocation = systemJaznLocation.replaceAll("\\\\", "/");
    System.out.println("Performing migration....");
    migrate(scriptLocation, source, destination, jaznFile,
      migrationFileEar, systemJaznLocation);
    System.out.println(".... Done .....");
  }

  public static void migrate(String scriptLocation, String source,
   String destination, String migrationFile,
    String migrationFileEar, String systemJaznLocation) throws IOException {
    StringBuilder builder = null;
    interpreter = new WLSTInterpreter();
    builder = new StringBuilder("sys.path.append('").append(scriptLocation)
      .append("')");
    interpreter.exec(builder.toString());
    interpreter.exec("import sys");
    interpreter.exec("import imp");
    interpreter.exec("import jpsWlstCmd");
    interpreter.exec("srcApp = None");
    interpreter.exec("dstApp = None");
    interpreter.exec("srcFolder = None");
    interpreter.exec("dstFolder = None");
    interpreter.exec("dstLdifFile = None");
    interpreter.exec("srcConfigFile = None");
    interpreter.exec("processPrivRole = None");
    interpreter.exec("resourceTypeFile = None");
    interpreter.exec("overWrite = None");
    interpreter.exec("migrateIdStoreMapping = None");
    interpreter.exec("preserveAppRoleGuid = None");
    interpreter.exec("reportFile = None");
    interpreter.exec("mode = None");
    String configFile =
      getGenerateMigrationJPSFile(source, destination,
        migrationFile, migrationFileEar, systemJaznLocation);
    configFile = configFile.replaceAll("\\\\", "/");
    builder =
        new StringBuilder("jpsWlstCmd.migrateSecurityStore("
          +"type=\"policyStore\", src=\"").append(source).append("\", dst=\"")
         .append(destination)
         .append("\", srcApp=srcApp, dstApp=dstApp, srcFolder=srcFolder,"
         +" dstFolder=dstFolder, dstLdifFile=dstLdifFile, "
         +"srcConfigFile=srcConfigFile, configFile=\"")
         .append(configFile).append("\", processPrivRole=processPrivRole, resourceTypeFile=resourceTypeFile, overWrite=overWrite, migrateIdStoreMapping=migrateIdStoreMapping, preserveAppRoleGuid=preserveAppRoleGuid, reportFile=reportFile, mode=mode)");
    interpreter.exec(builder.toString());
  }

  private static String getGenerateMigrationJPSFile(String source, String destination, String fileName, String earFile,
    String systemJaznLocation) throws IOException {

    File tmpFileLocation = new File(DEFAULT_TMP_LOCATION);
    if(!tmpFileLocation.exists()) {
      tmpFileLocation.mkdirs();
    }

    String fileContent = StreamUtil.drainToString(
      new FileReader(DEFAULT_MIGRATION_SCRIPT_LOCATION));
    String jaznFile = formulateMigrationJAZNFile(
      fileName, earFile, tmpFileLocation);
    jaznFile = jaznFile.replaceAll("\\\\", "/");
    fileContent = MessageFormat.format(fileContent, 
      source, destination, systemJaznLocation, jaznFile);
    File tempFile = createTemporaryFile(fileContent,
       "migrate-jps-config", ".xml", tmpFileLocation);
    return tempFile.getCanonicalPath();
  }

  private static File createTemporaryFile(String prefix, String suffix,
    File tmpFileLocation) throws java.io.IOException,
     java.io.FileNotFoundException {
    File tempFile = File.createTempFile(prefix, suffix, tmpFileLocation);
    tempFile.deleteOnExit();
    return tempFile;
  }

  private static File createTemporaryFile(String fileContent,
    String prefix, String suffix,
    File tmpFileLocation) throws java.io.IOException, 
      java.io.FileNotFoundException {
    File tempFile = createTemporaryFile(prefix, suffix, tmpFileLocation);
    FileOutputStream fos = new FileOutputStream(tempFile);


    IOUtils.write(fileContent, fos);
    IOUtils.closeQuietly(fos);
    return tempFile;
  }

  private static String formulateMigrationJAZNFile(String fileName,
     String earFileName,
    File tmpFileLocation) throws IOException {
    if(fileName != null && fileName.trim().length() > 0) {
      return fileName;
    }

    ZipFile zipFile = new ZipFile(earFileName);
    Enumeration entries = zipFile.entries();
    while(entries.hasMoreElements()) {
      ZipEntry entry = (ZipEntry) entries.nextElement();
      if(!entry.isDirectory()) {
        if(entry.getName().endsWith(DEFAULT_JAZN_SUFFIX)) {
          File tempFile = createTemporaryFile("jazn-data-orig",
            ".xml", tmpFileLocation);
          FileOutputStream fos = new FileOutputStream(tempFile);
          IOUtils.copy(zipFile.getInputStream(entry), fos);
          IOUtils.closeQuietly(fos);
          return tempFile.getCanonicalPath();
        }
      }
    }
    return null;
  }
  private static Options createOptions() {
    Options options = new Options();
    Option source = new Option(SOURCE_OPTION_NAME, 
      "src", true, "source policy config name : defaults appPolicy");
    Option destination =
      new Option(DESTINATION_OPTION_NAME, "dst", true, 
       "destination policy config name : defaults domainPolicy");
    Option scriptLocation =
      new Option(SCRIPT_OPTION_NAME, "script", true, 
       "Loction of all the .py scripts to run wlst");
    Option migrationFile = new Option(JAZN_OPTION_NAME,
      "jazn", true, "jazn file to import location");
    Option systemJaznLocation =
      new Option(SYSJAZN_OPTION_NAME, "sysjazn", true, 
       "system jazn file to copy to full location");
    Option migrationFileEar =
      new Option(EAR_OPTION_NAME, "ear", true, 
       "Ear file to extract jazn file from : cant be used with jazn");
    source.setOptionalArg(true);
    destination.setOptionalArg(true);
    scriptLocation.setOptionalArg(true);
    systemJaznLocation.setRequired(true);
    migrationFile.setOptionalArg(true);
    migrationFileEar.setOptionalArg(true);

    options.addOption(source);
    options.addOption(destination);
    options.addOption(scriptLocation);
    options.addOption(migrationFile);
    options.addOption(systemJaznLocation);
    options.addOption(migrationFileEar);
    return options;
  }
}

Wednesday, March 7, 2012

Weblogic and ADF: Unintended Consequences new session between weblogic apps and our project structure

Ok so a bit of background the following is our project stucture and all works well between applications that are deployed on one weblogic server they share sessions and user principals and roles.

This setup allows us seperate jazn files across projects and to keep everything contained.

Our base application is common which contains a set of projects for view, model, and common java code

Common >
    LoginModule (JAAS stuff)
    Common (java code)
    Model (company wide common model components)
    View (company wide common model components)

Shared Model
    Model (All common lov, eo, vo files used across projects : NO Application Modules here)

Various applications deployed as ears like finance, reports etc that contain Model and View projects
 
Home - this is the glue that binds all our applications together in a single menu etc it has NO dependacies on the other ear applications.
  View (Menu code)

Ok so onto the problem - when logging into our home app and navigating to any other of our projects from the menu we now have to relogin not great but once the second login was done all was well with the app. I did some debugging and found on the redirect we go a new session id - weird. So I puzzeled it out when making changes for the automated login I added a property to the weblogic.xml in my view project. I removed this and everything worked as before.

The offending property:
<session-descriptor>
    <cookie-path>/home</cookie-path>
</session-descriptor>

Tuesday, March 6, 2012

ADF errors with template binding for templates within templates

I refactored my templates to contain templates within templates and all new screens I created stopped working.

By not working my binding where not found using my utils methods to get the DCBindingContainer.

For some reason when I created screens of my new templates it includes an extra form tag and binds my template to a page variable in the bindings <page path="za.co.test.pageDefs.defaultFormTemplatePageDef" id="ptb1" Refresh="ifNeeded"/>. If I remove the form tags and remove the page variable and its binding to my template all is good.

Hopefully this saves you some time.

Monday, March 5, 2012

ADF : MDS-00013: no metadata found for metadata object

Weird error happend on one of my screens when I tried to call it, all my other screens worked perfectly.

Removed the two MDS jars from my Model and View projects and like magic errors appeared in my build.

Fixed up the errors (mainly related to refactoring and windows not recognising a difference in upper/ lowercase). Also had to do a clean before I built and remove the project directory in the o.j2ee folder.


NOTE: Refactoring and changing case is dangerous.
Also had this error where I had misspelt a task flow name.


Tuesday, February 28, 2012

ADF popups : Note to self

When using a popup dont have a trigger from your button onto the area in which your popup is.

Behaviour: popup.show in code brought back nothing no popup and the code works elsewhere.
Solution: move the popup to an area outside of the refreshed area.


Friday, February 24, 2012

ADF_FACES-30124 Multiple forms detected on viewId: Rich client currently has some limitations in dealing with multiple forms

Check for multiple af:form tags in your page - there might be one in your template if you are using one.

Really now wtf : Jdeveloper 11.1.1.6 released

Warning Rant to follow :
So where is 11.1.2.2 which has weblogic 10.3.6 and why two streams why not migrate the SOA/ Webcentre stuff etc to 11.1.2 and be done with it. I vote for one stream for all.

Interesting addtitions:
Drag and Drop on Touch Devices: On touch devices like tablets, the component drag and drop has a different gesture than with the mouse. An item that can be dragged must activated by a tap and hold gesture. The item will change its appearance to indicate that it can be dragged once held long enough. The same gesture applies to reordering table columns. Tap and hold the column header, then drag it to reorder the columns.

MySQL Support: ADF Business Components have been tested with MySQL 5.5

Improved Compression of JavaScript: By using improved obfuscation techniques, the size of the compressed ADF JavaScript libraries has decreased by an average of 20% across all libraries.

https://blogs.oracle.com/jdeveloperpm/entry/jdeveloper_11_1_1_6
http://www.oracle.com/technetwork/developer-tools/jdev/downloads/jdeveloper11116-1377208.html

Thursday, February 23, 2012

ADF: Help my pages have dissapered from jazn-data.xml configuration

I opened my jazn-data and I had no task flows and web pages in the resource grants section.
Shock and horror : I had made sure the show resource with and without grants was on (little lock and key icons) still not happening.

Then I realized my mistake : ALWAYS have your Source Project set correctly to the view project mine was set to my build project. *embarrassed*





Wednesday, February 22, 2012

Hudson ADF ojdeploy build failure (Too many open files)

I moved our hudson server  (just zip up the $HUDSON_HOME directory and copy it across very easy) to a new redhat machine and the builds started failing with the error (Too many open files).

This indicates that my open file limit has been reached for my user. - check this with the
ulimit -n [this command check the users limit for open files ulimit -a to check all limits]
and lsof -p <pid> | wc -l [get the pid by doing a ps -ef | grep hudson]

To address this the easy way vi /etc/security/limits.conf and add/ edt the following lines (my was the default 1024):
* soft nofile 2048
* hard nofile 2048


Tuesday, February 21, 2012

ADF : Automated testing lessons learned

Ok needed to help with some performance testing of our ADF apps login process and struggled a bit with some of the stuff so here are my findings:

Firefox and Tamper Data: https://addons.mozilla.org/en-US/firefox/addon/tamper-data/

So so handy for catching all your post and get parameters cookies and headers. A must for automated testing to see what is going on in your app. More of a diagnostic tool.

JMeter:  http://jmeter.apache.org/
Really really cool once I had found Chris Muirs post on setting up jmeter for ADF. (link below).
You can make complicated test cases here very easily and run them any number of times in the ide.
Very handy for doing volume testing.

BadBoy: http://www.badboy.com.au/
If you want something that will record what you are doing/ click in your browser and export your scripts to JMeter for automated testing this is the tool for you.

Selenium:http://seleniumhq.org/
Holy moly this is so easy to use and test with - just fire up firefox start the selenium ide add on and start recording - everything just WORKS. You can export this to junit tests and watch as all the magic happens. Really really cool.


Also dont try anything fancy with the login just use j_username and j_password posting to j_security_check. See attached script. http://dl.dropbox.com/u/63575405/Script.jmx

http://one-size-doesnt-fit-all.blogspot.com/2010/04/configuring-apache-jmeter-specifically.html

I like the selenium using unit tests for most of my stuff but I find jmeter incredibly handy for quick perfomance testing.


Friday, February 17, 2012

Nexus vs Artifactory : My experience


Nexus : 1.9.2.4
Artifactory : 2.3.3.1

We needed a repository manager for our maven builds and decided to evaluate  Nexus (I had used Artifactory many time before and needed no evaluation).

I found the Nexus UI was slicker and easier to use than Artifactory also like the file system storage idea. Very cool product.

Unfortunatley we ran into some issues the Nexus builds we were doing where slower and kept timing out and blocking the repos.
(The error was : this is 3 (re)try, cause: java.net.SocketException: Connection reset)
NOTE: we are going through a proxy to get to the internet and could be the cause of the Nexus problem

This was probably a configuration issue but I could not find a solution easily.
So hi-ho hi-ho its back to Artifactory we go.