As a Java developer, moving to Flash should not be too difficult of a task. Actionscript 3.0 contains many features of the Java language, but also has tremendous amount of other features related to animations that Java does not have. It is these latter features that will require a slower learning curve for a Java developer. Here are couple of important similarities and differences that I have encountered related to the design, structure and syntax of the Actionscript language as I was reading a book. These differences are more oriented toward a Java developer moving to Actionscript as opposed to a Flash developer moving to Java.
Conceptual Differences
1. Variable declaration
Variables in Actionscript do not have a type, as opposed to Java where all variables must be assigned a type. Although one could stipulate that assigning a Java variable as a java.lang.Object could simulate an untyped Actionscript variable, the same can be done to an Actionscript variable. Although, the variable of a type Object is still a typed variable. The difference lies in the fact that an untyped Actionscript variable can be assigned a primitive data type value or an Object type, where in Java it would not be possible for a single variable to be assigned both a primitive data type and an Object at the same time.
2. Function declaration
Despite the syntactical differences, there are also two conceptual differences in function/method declarations between Actionscript and Java.
(1) The first difference is that functions do not need to declare a return type. This is to support older versions of Actionscript.
(2) The second is that functions can declare initial values for its parameters in Actionscript. Initialized parameters of a function are not required to be passed to the function, while uninitialized parameters of a function are required to be passed. Whether they will cause compile errors is something i do not yet know.
3. Function passed as value
One of the more powerful features in Actionscript is the ability to assign a variable to a reference to a function. This is quite a powerful feature in Actionscript and perhaps provides a short cut for coding.
This feature is actually used for event handling and animation, the forte of Actionscript.
4. Nested Functions
Functions can be declared within another function.
5. Package-level, Source-File-Level, And Global Functions
One can create functions within a package (package-level). Package-level functions are accessible only within the package.
Source-file-level functions are rarely used because they can be replaced with private static functions within a package.
Global functions are defined in the unnamed package and are accessible by any class or package without an import.
All these are not concepts within Java. In Java, all functions are always associated with a class.
6. Protected and default access-control modifiers.
The protected and default access modifiers of Actionscript and Java have different definitions. The protected modifier in Java allows classes within the same package and any subclasses to access the class or variable on which the protected modifier has been declared, while in Actionscript, the protected modifier allows only subclasses to access the class or variable. Therefore, the Actionscript modifier is more restrictive, but in my opinion, makes more sense.
The default modifier in Java, which is designated with no keyword but aka package-private, only allows classes within the same package to access the class or variable, while, in Actionscript, the default or internal modifier allows classes within the same package and subclasses to access the class or variable. Essentially, the internal modifier has the same access control as in Java's protected modifier.
8. Overloading Methods in Subclasses
9. No Abstract Classes
10. Reflection replaced with built-in operators.
11. Arrays are different in Actionscript.
Arrays in Actionscript are not associated with a particular class or type as in Java. So, there is only one array type in Actionscript as opposed to Java where there can be an infinite number of array types according to the type the array has been declared with. This single array type in Actionscript is used to hold all types within the same array.
The array in Actionscript is also dynamically sized and therefore will never throw an error if the initial capacity of the array has been exceeded when attempting to add new elements beyond the size of the array. In Java, an array is always initialized with an initial capacity and cannot be changed after instantiation. Instead, the ArrayList can be used in place of the fixed-sized array.
Unlike the Java array, the Actionscript array has methods used for modifying its contents. Both array types allow you to directly modify its contents using the bracket notation. However, the Actionscript array defines modification methods, listed in the following: push, unshift, splice, shift, pop, concat, delete. This allows the array to be used as a stack.
One other trivial but nice feature of the Actionscript array is that it prints out as a comma-delimited list of element values. No more weird string representations of arrays! (Athough in Java 1.5, there is a new method that prints out Arrays nicely, Arrays.toString()).
12. Dynamic Actionscript
An entirely different concept in Actionscript is the ability to dynamically create or add new instance variables and methods to classes or dynamically create new classes. There is no analogous concept in Java.
Only Actionscript classes that have been defined as
13. Actionscript Lookup Tables versus Java Collections Map
The Java Collections framework has revolutionalized the way Java developers use data structures in their programs. The lead designer of the Collections Framework, Joshua Bloch, who also wrote a highly acclaimed and one of the most useful Java programming books, called Effective Java, is a prominent Java architect among the Java community. His framework has won an award for Best Java Class Library.
One of the collection classes in the framework is a Map. There is not equivalent class in Actionscript. Instead, the ability to dynamically add instance variables to a dynamic object replaces the Map concept.
Feature Differences
1. Setter / Getter functions
2. Constants and the final modifier for instance variables.
3. The switch statement is more powerful in Actionscript.
The Java switch statement only allows the primitive data types to used as values in the switch statement. One of the complaints in Java is that you cannot use Strings or perhaps Objects within the switch statement. Fortunately, in Actionscript, you can! However, there is fine print related with this feature. In a switch statement, it uses a strict equality operator on determining equality of the switch values.
4. Actionscript has additional operators that Java does not have. Some are quite powerful.
Some of these additional operators include those that backwards-compatible for older versions of Actionscript. These will not be included here as they should not be used in new code.
5. Actionscript has built-in XML operators.
Syntactical Differences
1. Constructors
2. Overriding methods
3. void vs. null
Conceptual Similarities
1. Object-oriented programming
Actionscript 3.0 contains interfaces, classes, instance methods, static methods, instance variables, static variables.
Friday, October 26, 2007
Tuesday, October 23, 2007
Flash Questions
1. Can two flash players embedded on the same page talk to each other?
2. Is it typical for flash players to be configured through a separate config file located on the machine?
3. NetStream is responsible for playing
2. Is it typical for flash players to be configured through a separate config file located on the machine?
3. NetStream is responsible for playing
Monday, October 22, 2007
Java To XML Technologies
I am trying to find the most suitable Java to XML utility that will provide easy to read XML that defines a Java object. Here are some sample ones below:
1. XML Encoder
sample:
JFrame class
XML:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.0" class="java.beans.XMLDecoder">
<object class="javax.swing.JFrame">
<void property="name">
<string>frame1</string>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>0</int>
<int>0</int>
<int>200</int>
<int>200</int>
</object>
</void>
<void property="contentPane">
<void method="add">
<object class="javax.swing.JButton">
<void property="label">
<string>Hello</string>
</void>
</object>
</void>
</void>
<void property="visible">
<boolean>true</boolean>
</void>
</object>
</java>
advantages:
sample XML:
N/A
advantages:
disadvantages:
sample:
Java:
advantages:
disadvantages:
4. Castor
References: Java Boutique Tutorial: Java To XML and Back Again with Castor XML
sample:
Java:
disadvantages:
5. Java2XML
References: Java Boutique Tutorial: Java To XML and Back Again with Castor XML
sample:
Java:
disadvantages:
References: Javaworld Article: Jato: The new kid on the open source block
disadvatages:
1. XML Encoder
sample:
JFrame class
XML:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.0" class="java.beans.XMLDecoder">
<object class="javax.swing.JFrame">
<void property="name">
<string>frame1</string>
</void>
<void property="bounds">
<object class="java.awt.Rectangle">
<int>0</int>
<int>0</int>
<int>200</int>
<int>200</int>
</object>
</void>
<void property="contentPane">
<void method="add">
<object class="javax.swing.JButton">
<void property="label">
<string>Hello</string>
</void>
</object>
</void>
</void>
<void property="visible">
<boolean>true</boolean>
</void>
</object>
</java>
advantages:
- completely comprehensive
- part of the Java API
- verbose
sample XML:
N/A
advantages:
disadvantages:
- not mature product
- not free
- no sample provided
sample:
Java:
public class Person {XML:
private String firstname;
private String lastname;
private PhoneNumber phone;
private PhoneNumber fax;
// ... constructors and methods
}
public class PhoneNumber {
private int code;
private String number;
// ... constructors and methods
}
<person>
<firstname>Joe</firstname>
<lastname>Walnes</lastname>
<phone>
<code>123</code>
<number>1234-456</number>
</phone>
<fax>
<code>123</code>
<number>9999-999</number>
</fax>
</person>
advantages:
- no mappings required
disadvantages:
4. Castor
References: Java Boutique Tutorial: Java To XML and Back Again with Castor XML
sample:
Java:
private List myList = new ArrayList();XML:
public void setMyList(List myList) {
this.myList = myList;
}
public List getMyList() {
return this.myList;
}
public Person(String name, String email, String phone, List myList) {
this.name = name;
this.email = email;
this.phone = phone;
this.myList = myList;
}
advantages:<?xml version="1.0" encoding="UTF-8"?>
<person>
<myList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="java:java.util.String">
List#1
</myList>
<myList xsi:type="java:java.util.String">
List#2
</myList>
<email>prokhorenko@gmail.com</email>
<name>Olexandr Prokhorenko</name>
<phone>123-555-1234</phone>
</person>
- comprehensive
- mature product
disadvantages:
- requires a mapping file
5. Java2XML
References: Java Boutique Tutorial: Java To XML and Back Again with Castor XML
sample:
Java:
public class HelloWorld
extends Thread
{
private int N;
private long sleep;
public HelloWorld(int N, long sleep)
{
this.N = N;
this.sleep = sleep;
}
public void run()
{
for (int i = 0; i < hw =" new"> XML:advantages:<!-- Generated by Java2XML http://java2xml.dev.java.net/ -->
<java-source-program>
<java-class-file name="helloworld.java">
<import module="java.util.*"/>
<class name="HelloWorld" visibility="public">
<superclass name="Thread"/>
<field name="N" visibility="private">
<type primitive="true" name="int"/>
</field>
<field name="sleep" visibility="private">
<type primitive="true" name="long"/>
</field>
<constructor visibility="public" name="HelloWorld">
<formal-arguments>
<formal-argument name="N">
<type primitive="true" name="int"/>
</formal-argument>
<formal-argument name="sleep">
<type primitive="true" name="long"/>
</formal-argument>
</formal-arguments>
<assignment-expr op="=">
<lvalue>
<field-access field="N">
<this/>
</field-access>
</lvalue>
<var-ref name="N"/>
</assignment-expr>
<assignment-expr op="=">
<lvalue>
<field-access field="sleep">
<this/>
</field-access>
</lvalue>
<var-ref name="sleep"/>
</assignment-expr>
</constructor>
<method name="run" visibility="public">
<type name="void" primitive="true"/>
<formal-arguments/>
<block>
<loop kind="for">
<init>
<local-variable name="i">
<type primitive="true" name="int"/>
<literal-number kind="interger" value="0"/>
</local-variable>
</init>
<test>
<binary-expr op="<">
<var-ref name="i"/>
<field-access field="N">
<this/>
</field-access>
</binary-expr>
</test>
<update>
<unary-expr op="++" post="true">
<var-ref name="i"/>
</unary-expr>
</update>
<block>
<send message="println">
<target>
<field-access field="out">
<var-ref name="System"/>
</field-access>
</target>
<arguments>
<literal-string value=""Hello World""/>
</arguments>
</send>
<try>
<block>
<send message="sleep">
<target>
<var-ref name="Thread"/>
</target>
<arguments>
<var-ref name="sleep"/>
</arguments>
</send>
</block>
<catch>
<formal-argument name="e">
<type name="InterruptedException"/>
</formal-argument>
<block>
<send message="printStackTrace">
<target>
<var-ref name="e"/>
</target>
<arguments/>
</send>
</block>
</catch>
</try>
</block>
</loop>
</block>
</method>
<method name="main" visibility="public" static="true">
<type name="void" primitive="true"/>
<formal-arguments>
<formal-argument name="args">
<type name="String" dimensions="1"/>
</formal-argument>
</formal-arguments>
<block>
<local-variable name="hw">
<type name="HelloWorld"/>
<new>
<type name="HelloWorld"/>
<arguments>
<literal-number kind="interger" value="10"/>
<literal-number kind="interger" value="1000"/>
</arguments>
</new>
</local-variable>
<send message="start">
<target>
<var-ref name="hw"/>
</target>
<arguments/>
</send>
</block>
</method>
</class>
</java-class-file>
</java-source-program>
- comprehensive
- mature product
- free
disadvantages:
- complicated XML
References: Javaworld Article: Jato: The new kid on the open source block
disadvatages:
- fairly new product
7. JiBX
advantages
disadvantages:
requires binding file to define the XML
Tuesday, October 16, 2007
JAXRPC Error - java.lang.ClassCastException
error
java.lang.ClassCastException
at com.sun.xml.rpc.client.StubBase._postSendingHook(StubBase.java:231)
at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:324)
at com.bamnetworks.services.boc.csp.client.impl.jaxrpc.generated.CspWsInterface_Stub.getPlanSummary(CspWsInterface_Stub.java:86)
at com.bamnetworks.services.boc.csp.client.CspClient.getMnCollegescholarshipInterface(CspClient.java:63)
environment
JAXRPC client resides inside Axis2 container.
The following jars are included in the Axis2 service lib: saaj-api.jar and saaj-impl.jar.
However, the Axis2 container also contains the following jar: axis2_saaj-1.1.jar
possible causes:
The above two jars are conflicting with each other. What is happening is that the axis2 saaj implementation of the message factory is being used instead of the sun saaj implementation of the message factory.
Therefore, the axis2 saaj implementation is creating messages that the JAX-RPC client is not expecting. It is expecting Message objects of a different type.
Axis2 saaj Message class: org.apache.axis2.saaj.SOAPMessageImpl
Sun saaj Message class: com.sun.xml.messaging.saaj.soap.MessagingImpl
It is this discrepancy in the classes that is causing the above ClassCastException. Within the StubBase it is expecting the type to be of the Sun implementation, but instead is getting the Axis 2 implementation.
solution
solution 1) Setting a system property and moving jars to the Axis 2 container lib
Move the saaj-impl.jar and FastInfoSet.jar to the Axis2 container lib from the Axis2 service's lib.
Then, within the code, set a system property that indicates which message factory should be used to construct SOAP messages for web services before the JAX-RPC client operation is called, as in the following code:
System.setProperty("javax.xml.soap.MessageFactory", "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Imp");
solution 2) Keep the JAXRPC jars in the service lib directory and modify the JAXRPC stub to use the correct MessageFactory.
This is particularly a hacky way of embedding a JAXRPC client within a Axis2 service, but this seems to be the only way to do without including the JAXRPC client jars in the Axis2 container lib.
In this solution, you need to modify the JAXRPC stub to
a) Create a custom MessageContext that extends from com.sun.xml.rpc.soap.message.SOAPMessageContext
In this custom class, override the methods called createMessage(useFastInfoset, acceptFastInfoset) and createMessage(useFastInfoset, acceptFastInfoset) to use the com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl() as the MessageFactory.
b) Create a custom ClientTransport that extends from HttpClientTransport.
In this custom class, override the readResponse() method.
java.lang.ClassCastException
at com.sun.xml.rpc.client.StubBase._postSendingHook(StubBase.java:231)
at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:324)
at com.bamnetworks.services.boc.csp.client.impl.jaxrpc.generated.CspWsInterface_Stub.getPlanSummary(CspWsInterface_Stub.java:86)
at com.bamnetworks.services.boc.csp.client.CspClient.getMnCollegescholarshipInterface(CspClient.java:63)
environment
JAXRPC client resides inside Axis2 container.
The following jars are included in the Axis2 service lib: saaj-api.jar and saaj-impl.jar.
However, the Axis2 container also contains the following jar: axis2_saaj-1.1.jar
possible causes:
The above two jars are conflicting with each other. What is happening is that the axis2 saaj implementation of the message factory is being used instead of the sun saaj implementation of the message factory.
Therefore, the axis2 saaj implementation is creating messages that the JAX-RPC client is not expecting. It is expecting Message objects of a different type.
Axis2 saaj Message class: org.apache.axis2.saaj.SOAPMessageImpl
Sun saaj Message class: com.sun.xml.messaging.saaj.soap.MessagingImpl
It is this discrepancy in the classes that is causing the above ClassCastException. Within the StubBase it is expecting the type to be of the Sun implementation, but instead is getting the Axis 2 implementation.
solution
solution 1) Setting a system property and moving jars to the Axis 2 container lib
Move the saaj-impl.jar and FastInfoSet.jar to the Axis2 container lib from the Axis2 service's lib.
Then, within the code, set a system property that indicates which message factory should be used to construct SOAP messages for web services before the JAX-RPC client operation is called, as in the following code:
System.setProperty("javax.xml.soap.MessageFactory", "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Imp");
solution 2) Keep the JAXRPC jars in the service lib directory and modify the JAXRPC stub to use the correct MessageFactory.
This is particularly a hacky way of embedding a JAXRPC client within a Axis2 service, but this seems to be the only way to do without including the JAXRPC client jars in the Axis2 container lib.
In this solution, you need to modify the JAXRPC stub to
a) Create a custom MessageContext that extends from com.sun.xml.rpc.soap.message.SOAPMessageContext
In this custom class, override the methods called createMessage(useFastInfoset, acceptFastInfoset) and createMessage(useFastInfoset, acceptFastInfoset) to use the com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl() as the MessageFactory.
b) Create a custom ClientTransport that extends from HttpClientTransport.
In this custom class, override the readResponse() method.
Friday, October 12, 2007
Detecting Broken Images with Javascript
An awesome link to determine whether the image is broken within the page. The following is exact copy from the link in the References below. Please refer to the link below.
<script language="javascript">
<!--
window.onload = function() {
for (var i = 0; i < document.images.length; i++) {
if (!IsImageOk(document.images[i])) {
document.images[i].style.visibility = "hidden";
}
}
};
function IsImageOk(img) {
// During the onload event, IE correctly identifies any images that
// weren't downloaded as not complete. Others should too. Gecko-based
// browsers act like NS4 in that they report this incorrectly.
if (!img.complete) {
return false;
}
// However, they do have two very useful properties: naturalWidth and
// naturalHeight. These give the true size of the image. If it failed
// to load, either of these should be zero.
if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
return false;
}
// No other way of checking: assume it's ok.
return true;
}
//-->
</script>
(If you feel that an exact copy of the code in this blog violates your rights, please tell me and I will take this code down. The link below will still remain. Thanks!)
References:
http://talideon.com/weblog/2005/02/detecting-broken-images-js.cfm
<script language="javascript">
<!--
window.onload = function() {
for (var i = 0; i < document.images.length; i++) {
if (!IsImageOk(document.images[i])) {
document.images[i].style.visibility = "hidden";
}
}
};
function IsImageOk(img) {
// During the onload event, IE correctly identifies any images that
// weren't downloaded as not complete. Others should too. Gecko-based
// browsers act like NS4 in that they report this incorrectly.
if (!img.complete) {
return false;
}
// However, they do have two very useful properties: naturalWidth and
// naturalHeight. These give the true size of the image. If it failed
// to load, either of these should be zero.
if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
return false;
}
// No other way of checking: assume it's ok.
return true;
}
//-->
</script>
(If you feel that an exact copy of the code in this blog violates your rights, please tell me and I will take this code down. The link below will still remain. Thanks!)
References:
http://talideon.com/weblog/2005/02/detecting-broken-images-js.cfm
Wednesday, October 10, 2007
Subscribe to:
Posts (Atom)