objective-c warning ‘class’ may not respond to ‘method’

This is a very interesting error message, you may want to look at the order of the method you are calling, and the code that causes the warning message. 
-(void) aMainMethod{
 [self testMethod] //call the method, warning occurs here
 ....
}
//here's the method you are calling
-(void) testMethod{
  NSLog(@"test");


If  your method is at somewhere after the code you call it (if it’s like above), move it so that it’s before the code (like the code below), and the warning should go away. Even with the warning, you should still be able to compile and run without any problem. 

//here's the method you are calling
-(void) testMethod{
NSLog(@"test");
}
-(void) aMainMethod{
[self testMethod] //no warning
....
}

Here’s an article about this with more details.

Advertisements

orange breakpoint in Xcode

While I was trying to debug in Xcode, some of my breakpoint turned to orange instead of normal blue color, and these points never got hit during debugging. What’s more is that whatever change I made to the code, it  doesn’t seem to compile.

Then I found this article about orange breakpoint, it suggests to disable Load Symbols Lazily in Xcode Preferences Debugging tab. I didn’t want to change the settings, so I just made a copy of my .m file (the one with issue), and delete the original one then import the new one. 

Everything works then…

Return cursor from Oracle global temporary tables, error ORA-01410: invalid ROWID

I have a stored procedure which does the following things:

  • insert input records into a global temporary table
  • create a cursor that selects record from another table that inner joins the temporary table
  • return the cursor

e.g.
OPEN p_cursor FOR
SELECT *
FROM emp
INNER JOIN temp_table
ON temp_table.department = emp.department;

Then I tried to execute the stored procedure from java code and I get ORA-01410: invalid ROWID error. If you google it, you’ll see the following explanation.

Cause: A ROWID was entered incorrectly. ROWIDs must be entered as formatted hexadecimal strings using only numbers and the characters A through F. A typical ROWID format is ‘000001F8.0001.0006’.
Action: Check the format, then enter the ROWID using the correct format. ROWID format: block ID, row in block, file ID

This doesn’t help me to solve the problem, but I found a thread on Oracle forum that mentioned about preserve rows (Global Temporary tables for returning resultsets to ODP.NET client app), so in my case, this error occurs because when creating the temporary table, it is set to ON COMMIT DELETE ROWS. To fix this just change it to ON COMMIT PRESERVE ROWS, so your records will still exist while you trying to get the resultset. e.g:

CREATE GLOBAL TEMPORARY TABLE temp_table (
department     VARCHAR2(50))
ON COMMIT PRESERVE ROWS;

[junit] java. lang.ClassNotFoundException while running ant script

This error is usually caused by having problem with classpath

You could get this for example while running the script for javac, or junit test. Make sure to add the lib folders you need, and the classes folder into the classpath. e.g. I have a main project with a model project (with hibernate), and before compile the main project, I’ve already built a jar for the model project and put it under the lib folder of the main one. It’ll look something like the following. Note: don’t forget to include the hibernate.cfg.xml file into classpath if you are using hibernate.

  <property name="build.main.dir"    location="/project/mainProject" />
<property name="build.model.dir"    location="/project/modelProject" />

<property name="class"    location="/project/build/classes" />
<path id="junit.classpath">
        <pathelement location="${build.main.dir}/classes"/>
        <pathelement location="${build.model.dir}/classes"/>
        <fileset dir="${build.model.dir}/classes">
            <include name="**/*.xml"/>
        </fileset>
</path>
<target  name="build">
<javac srcdir="${build.main.dir}/src" destdir="${classes}"   debug="on" >
 <include name="**/*.java"/>
<classpath refid="main.classpath" />
</javac>
<javac srcdir="${build.main.dir}/test" destdir="${classes}"   debug="on" >
 <include name="**/*.java"/>
<classpath refid="main.classpath" />
</javac>
</target>

For junit case, there’re more stuffs to pay attention to:

1) make sure you referenced to the junit libs, they are NOT included in the ant distribution, reference to this junit test manual from ant. Basically you can put junit.jar and ant-junit.jar under ant’s lib folder, or reference that two classes in your classpath variable.

2) remember to build the test classes as well, like the example above included the test folder. 

3) add the above test classes to the classpath.

4) if your junit testing include calls to database through hibernate, do not use the jdbc connection that’s setup in the sun application server, so in hibernate.cfg.xml it should be something like this

<property name="connection.url">jdbc:oracle:thin:@123.456.78:test</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>

instead of 
<property name="connection.datasource">jdbc/testProject</property>

Hibernate with Oracle XmlType

The solution is based on Mapping Oracle XmlType to Document from the Hibernate’s website. I don’t need to use C3P0 though.

package mypackage.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;import oracle.jdbc.OracleResultSet;
import oracle.sql.OPAQUE;
import oracle.xdb.XMLType;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
public class HibernateXMLType implements UserType, Serializable {

private static final long serialVersionUID = 2308230823023l;
private static final Class returnedClass = Document.class;
private static final int[] SQL_TYPES = new int[] { oracle.xdb.XMLType._SQL_TYPECODE };

public int[] sqlTypes() {
return SQL_TYPES;
}

public Class returnedClass() {
return returnedClass;
}

public int hashCode(Object _obj) {
return _obj.hashCode();
}

public Object assemble(Serializable _cached, Object _owner)
throws HibernateException
{
try {
return HibernateXMLType.stringToDom((String)_cached);
}
catch (Exception e) {
throw new HibernateException(“Could not assemble String to Document”, e);
}
}

public Serializable disassemble(Object _obj)
throws HibernateException
{
try {
return HibernateXMLType.domToString((Document)_obj);
}
catch (Exception e) {
throw new HibernateException(“Could not disassemble Document to Serializable”, e);
}
}

public Object replace(Object _orig, Object _tar, Object _owner) {
return deepCopy(_orig);
}

public boolean equals(Object arg0, Object arg1)
throws HibernateException
{
if(arg0 == null && arg1 == null) return true;
else if (arg0 == null && arg1 != null ) return false;
else return arg0.equals(arg1);
}

public Object nullSafeGet( ResultSet rs, String [ ] names, Object arg2 )
throws HibernateException, SQLException
{
XMLType xmlType = null;
Document doc = null;
try {
OPAQUE op = null;
OracleResultSet ors = null;
if (rs instanceof OracleResultSet) {
ors = (OracleResultSet)rs;
} else {
throw new UnsupportedOperationException(“ResultSet needs to be of type OracleResultSet”);
}
op = ors.getOPAQUE(names[0]);
if(op != null) {
xmlType = XMLType.createXML ( op );
}
doc = xmlType.getDOM();
}finally {
if (null != xmlType) {
xmlType.close();
}
}
return doc;
}

public void nullSafeSet( PreparedStatement st, Object value, int index )
throws HibernateException, SQLException
{
try {
XMLType xmlType = null;
if (value != null) {
xmlType = XMLType.createXML(st.getConnection(),HibernateXMLType.domToString((Document)value));
}
st.setObject(index, xmlType);
}
catch (Exception e) {
throw new SQLException(“Could not convert Document to String for storage”);
}
}

public Object deepCopy(Object value)
throws HibernateException
{
if (value == null) return null;

return (Document)((Document)value).cloneNode(true);
}

public boolean isMutable() {
return false;
}

public static String domToString(Document _document)
throws TransformerException
{
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, “yes”);
DOMSource source = new DOMSource(_document);
StringWriter sw=new StringWriter();
StreamResult result = new StreamResult(sw);
transformer.transform(source, result);
return sw.toString();
}

public static Document stringToDom(String xmlSource)
throws SAXException, ParserConfigurationException, IOException
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new ByteArrayInputStream(xmlSource.getBytes(“UTF-8”)));
}
}

In the hbm.xml file set the property to be:

<property
name=”xmlMessage”
type=”mypackage.util.HibernateXMLType”
column=”MESSAGE_XML”
/>

In the .java file set the field to be:

private Document  xmlMessage;public Document getXmlMessage() {
return xmlMessage;
}public void setXmlMessage(Document xmlMessage) {
this.xmlMessage= xmlMessage;
}

css: same table with colspan and rowspan

I found this really simple but interesting use of colspan and rowspan in the same table example

Here’s a example:

   
   
 

<table style="height: 100px;" border="0" cellspacing="0" cellpadding="0" width="100px">
  <tr>
    <td style="background-color:yellow" colspan="2"> 
    </td>
    <td style="background-color:red" rowspan="2">
    </td>
  </tr>
 <tr>
    <td style="background-color:orange" rowspan="2"> 
    </td>
    <td> 
    </td>
  </tr>
  <tr>
    <td style="background-color:gray" colspan="2">
</td>
  </tr>
</table>

Nice…

Referencing issue with asp.net Master page (where the content page is in a different folder)

Content page works fine when the master page is in the same folder, but when they are not, the content page will just give you the cross or question mark error image because the URL is relevant to the content page. 

There are several ways to deal with this issue, and I found the following book on google scholar really helpful:

Core Internet Application Development with ASP.NET 2.0

For example, if you have a master page called main.master right under the project ‘ TestProject’ and have a content page ‘content.aspx’ under a folder called ‘Folder’.

Suppose an image on the master page is <img src=”images/logo.gif”>, which stores in a folder calls ‘images’ under master folder.

You can choose to use ~ symbol like this
<asp:Image runat=”server” id=”testImage” ImageUrl=”~/master/images/logo.gif”/>

However this only works for server control.

The second way is to use absolute path like the following:

<img src=”/master/images/logo.gif”>

What I tried is to put almost all image references in the master page to css file (which is not many), and then reference my master page using the absolute path, so that the master page use the absolute path to read the css file, while whatever in css file does not need to be changed. 

 

CSS: Gaps between td, div and table

The little gap between td(s) and the gap between the border of a table to a border of a div is just annoying. Here’s the before and after.
Before:
<table border="0">
  <tr>
    <td style="border: solid 3px gray;border-bottom:none">
      1st row
   </td>
  </tr>
  <tr>
    <td style="border:solid 3px red; border-top:none">
      2nd row
    </td>
  </tr>
</table>

1st row

2nd row

div1

After: if we modify margin, padding, (cellspacing, cellpadding for tables only) properties of table and div to 0, it’ll look fine then:

<table border="0" cellspacing="0">
  <tr>
    <td style="border: solid 3px gray;border-bottom:none">
     <div>
        1st row
      </div>
    </td>
  </tr>
  <tr>
    <td style="border:solid 3px red; border-top:none">
      2nd row
   </td>
  </tr>
</table>
<div style="border:solid 3px yellow;margin:0;">div 2</div>

1st row

2nd row

div2

Application Setting in VB and C#

Application setting can be user-scoped or application-scoped. The user scoped one can be read and write at runtime.For example, assign value Variabl1 to a user-scoped application setting will be like the following

VB:

My.Settings.Sample=Variable1

C#:

Properties.Settings.Default.Sample=Variable1;
Properties.Settings.Default.Upgrade();
Properties.Settings.Default.Save();

The user.config file will be stored against the logged in user,

Windows XP:
C:\Documents and Settings\username\Local Settings\Application Data\companyname\Applicationname\application.exe$%^&*1.1.0.0

Vista:
C:\Users\username\AppData\Local\ApplicationName\application.exe@#$%^\1.1.0.0