Ant Tasks for Websphere Deployment

The following is my ant for websphere deployment, application start & stop, etc. The complete API doc can be found in IBM website: https://publib.boulder.ibm.com/infocenter/dmndhelp/v6rxmx/index.jsp?topic=/com.ibm.wsps.602.javadoc.doc/doc/index.html
For this tasks to run, you need to have the jar file com.ibm.ws.runtime.jar. This jar file can be found in plugins directory of your Websphere installation.

<property name="hostName" value="localhost" />
<property name="connType" value="SOAP" />
<property name="port" value="8880" />
<property name="deployEar.dir" value="C:\Users\firmanw\Documents\zw2\OSMS\build" />
<property name="deployEar" value="osms.war" />
<property name="wasHome.dir" value="C:\Program Files (x86)\IBM\TeamConcert\runtimes\base_v7" />
<property name="app.name" value="osms_war" />
<property name="profile.name" value="profilexfirman" />
<taskdef name="wsInstallApp" classname="com.ibm.websphere.ant.tasks.InstallApplication" classpath="com.ibm.ws.runtime.jar" />
<taskdef name="wsStartApplication" classname="com.ibm.websphere.ant.tasks.StartApplication" classpath="com.ibm.ws.runtime.jar" />
<taskdef name="wsStopApplication" classname="com.ibm.websphere.ant.tasks.StopApplication" classpath="com.ibm.ws.runtime.jar" />
<target name="installEar" depends="build.osms">
<echo message="Deployable EAR File found at: ${deployEar.dir}/${deployEar}" />
<wsInstallApp ear="${deployEar.dir}/${deployEar}" wasHome="${wasHome.dir}" conntype="${connType}" port="${port}" host="${hostName}" profilename="profilexfirman" options="-appname ${app.name} -usedefaultbindings -update" />
</target>
<target name="startInstallEar" depends="installEar">
<echo message="Mulai ngestart" />
<wsStartApplication wasHome="${wasHome.dir}" conntype="${connType}" port="${port}" host="${hostName}" profilename="${profile.name}" application="${app.name}" />
</target>
<target name="startEar">
<echo message="Mulai ngestart" />
<wsStartApplication wasHome="${wasHome.dir}" conntype="${connType}" port="${port}" host="${hostName}" profilename="${profile.name}" application="${app.name}" />
</target>
<target name="stopEar">
<echo message="Mulai nyetop" />
<wsStopApplication wasHome="${wasHome.dir}" conntype="${connType}" port="${port}" host="${hostName}" profilename="${profile.name}" application="${app.name}" />
</target>

<target name="restartEar" depends="stopEar, startEar"></target>

Websphere hot deployment and dynamic reloading

In the office we use Websphere AS and RAD as IDE. When you make changes to a Java class file, the changes are publised by the IDE to the AS, and the server restarts for the changes to take effect. This is in contrast to the changes done to JSP which do not require server restart to take effect. Actually there is a possibility of hot deployment and dynamic reloading (http://publib.boulder.ibm.com/infocenter/wsdoc400/v6r0/index.jsp?topic=/com.ibm.websphere.iseries.doc/info/ae/ae/trun_app_hotupgrade.html) which basically works like this: you replace the class file in the server with the new class file and the changes should take effect immediately without needing server restart. This is a very useful feature of WAS and it makes me wonder why the WAS plugin for RAD/Eclipse does not have a feature to enable this. I know there are limitations, like when you replace Hibernate entities or deployment descriptor, then you still need to restart the server but generally this feature is very useful during development.

So i decided to write an ant build file which runs when there is an automatic build. The job of this build file is basically to replace the class files in the server with the newly built class files in the workspace.

To do this, I first need to manually deploy the EAR via the WAS console. This is to make the exploded EAR file available in the server. Because when i deploy the ear by right clicking on the project -> run as -> run in the server, the exploded ear file is not there in the server! I dont know where, probably in one of the numerous plugin directories of the RAD/Eclipse installation.

After the ear file is manually deployed, then disable automatic publishing in the WAS plugin.


And then the ant build file:



Pretty obvious I guess. The src.osms is the workspace build directory while the des.osms is the WAS exploded ear directory. The most important part of the build file is the mnodified selector (https://ant.apache.org/manual/Types/selectors.html#modified) which selects only recently modified file (which is the file newly built by Eclipse automatic build) and copies these files to WAS.

Now, this ant build file needs to run everytime you modify a class file or anything, so enable automatic build on your project.

And then right click on your project -> properties -> builders -> new -> ant builders -> OK. You get this dialog
Choose your ant build file. Then click on the target tab and set the target for manual build and auto build. Done.


PS: if you have money, try JRebel.

Migrating app from Glassfish to JBoss

I have trying to port app written for Glassfish to JBoss Wildfly, since i met numerous issues with Glassfish. The default JPA impl for Glassfish is EclipseLink, while for Wildfly it is hibernate. I wanted to keep using EclipseLink in Wildfly.

1. Download eclipselink. http://www.eclipse.org/eclipselink/downloads/

2. Unzip it, copy the eclipselink.jar to modules/system/layers/base/org/eclipse/persistence/main

3. Update module.xml in the directory to reflect the change:
























Make sure to match the exact name of the jar file in module.xml. If the jar file includes version numbers, for example, this should be reflected in module.xml file.

3. Execute the following while Wildfly is running:

jboss-cli.sh --connect '/system-property=eclipselink.archive.factory:add(value=org.jipijapa.eclipselink.JBossArchiveFactoryImpl)'

Or alternatively, modify standalone.xml to add the following:


4. Add the following dependence to pom.xml. Make sure the version matches the version of eclipselink jar you copied in Wildfly directory in step 2.








5. Define the provider for eclipselink in persistence.xml












Note that if the provider tag in persistence.xml is removed, then the app server will fallback to the default JPA implementation, which is hibernate for Wildfly and eclipselink for Glassfish.


Changing default JDK in Mac OS X Mavericks

So i have two installations of JDK on my Mac OS X. 1.7 and 1.8. The following is to list all JDK in Mac.


/usr/libexec/java_home -V

The above command resulted in the following:

Matching Java Virtual Machines (2):
    1.8.0_05, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home
    1.7.0_25, x86_64: "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home

Because of some problem with Spring when using Java 8, i need to change the default back to Java 7. This is what i do to the .profile file in my home directory.

export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
#export JAVA_HOME=`/usr/libexec/java_home -v 1.8`

Sorted!

Data Import IMPDP Failed

So basically i was trying to import a dump file for schema rcemca into schema rcecms. (on a side note: you create schema by creating user. So each user has its own schema). I created the IMPDP_DIR by the following:

create directory IMPDP_DIR as '/home/firman/Downloads'
grant read, write on IMPDP_DIR to rcecms
commit


I then queried the database to makes sure the newly created directory is there
select * from all_directories


It was there.

OWNER       DIRECTORY_NAME
------------------------------ ------------------------------
DIRECTORY_PATH
--------------------------------------------------------------------------------
SYS       EXPDP_DIR
/home/firman/Downloads

SYS       XMLDIR
/u01/app/oracle/product/11.2.0/xe/rdbms/xml

SYS       DATA_PUMP_DIR

/u01/app/oracle/admin/XE/dpdump/

And then I did:
impdp system/password DIRECTORY=IMPDP_DIR DUMPFILE=file.dmp schemas=rcemca remap_schema=rcemca:rcecms


But i got the following error:

ORA-39002: invalid operation
ORA-39070: Unable to open the log file.
ORA-29283: invalid file operation
ORA-06512: at "SYS.UTL_FILE", line 536
ORA-29283: invalid file operation

After some searches i figured out it was because the user oracle, which ultimately runs the necessary steps to import the data, which is different from the user with which i ran the impdp command, has no access to the /home/firman/Downloads directory. A permission problem. This was fixed by changing the permission of /home/firman/Downloads or better still, moving the dump file to the Oracle provided data pump directory, which is DATA_PUMP_DIR (query above).

JNDI Lookup of EJB from stand alone client on JBoss AS 7.1

I followed the examples explained in the following JBoss official links:

https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI

https://docs.jboss.org/author/display/AS71/Remote+EJB+invocations+via+JNDI+-+EJB+client+API+or+remote-naming+project

This is my lookup method:

private static Hello lookupRemoteStatelessCalculator() throws NamingException {
final Hashtable jndiProperties = new Hashtable();
jndiProperties.put("jboss.naming.client.ejb.context", true);
jndiProperties.put(Context.URL_PKG_PREFIXES,
"org.jboss.ejb.client.naming");
jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(Context.PROVIDER_URL,"remote://localhost:4447");
// username
jndiProperties.put(Context.SECURITY_PRINCIPAL, "admin");
// password
jndiProperties.put(Context.SECURITY_CREDENTIALS, "password");
final Context context = new InitialContext(jndiProperties);
// The app name is the application name of the deployed EJBs. This is
// typically the ear name
// without the .ear suffix. However, the application name could be
// overridden in the application.xml of the
// EJB deployment on the server.
// Since we haven't deployed the application as a .ear, the app name for
// us will be an empty string
final String appName = "";
// This is the module name of the deployed EJBs on the server. This is
// typically the jar name of the
// EJB deployment, without the .jar suffix, but can be overridden via
// the ejb-jar.xml
// In this example, we have deployed the EJBs in a
// jboss-as-ejb-remote-app.jar, so the module name is
// jboss-as-ejb-remote-app
final String moduleName = "jbosslookup";
// AS7 allows each deployment to have an (optional) distinct name. We
// haven't specified a distinct name for
// our EJB deployment, so this is an empty string
final String distinctName = "";
// The EJB name which by default is the simple class name of the bean
// implementation class
final String beanName = HelloBean.class.getSimpleName();
// the remote view fully qualified class name
final String viewClassName = Hello.class.getName();
// let's do the lookup
System.out.println("ejb:" + appName + "/"
+ moduleName + "/" + distinctName + "/" + beanName + "!"
+ viewClassName);
return (Hello) context.lookup("ejb:" + appName + "/"
+ moduleName + "/" + distinctName + "/" + beanName + "!"
+ viewClassName);

}

You need to have username and password set up on the server as application user. This username and password credential is used by the client when creating the initial context. This information along with other information is passed as Properties argument into the initial context constructor.

And then, you need to have the jboss-client.jar in the classpath of the client.

But  when i ran the client, i kept getting the following exception:


Exception in thread "main" java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/ejb/NoSuchEJBException

It turned out that i need to replace the dependency:

     javax
     javaee-api
     6.0
     provided

With the following JBoss implementation dependency:

         <dependency>
            <groupId>org.jboss.spec</groupId>
            <artifactId>jboss-javaee-6.0</artifactId>
            <version>3.0.2.Final</version>
            <type>pom</type>
            <scope>provided</scope>
       </dependency>

But it was  not enough. JBoss wants me to specify the Xalan dependency too.

        <dependency>
            <groupId>xalan</groupId>
            <artifactId>xalan</artifactId>
            <version>2.7.1</version>
            <scope>provided</scope>
        </dependency> 

Java EE dependency does not have implementation in maven repo, that`s what caused the exception. You also need implementation specific dependency when doing unit tests. I read that this issue is solved in Java EE 7 but i haven`t tested this yet.

Fix Java 7 installation on Mac

So i installed Sun Oracle JDK 7 on my Mac. I unzipped Eclipse into /Applications. I opened launcher, trying to launch Eclipse from there.

But a dialog box popped up asking me to install Java 6 in order to run Eclipse.

This is in part due to Oracle's missing definitions of the JRE7 VM capabilities.

Copy the Info.plist located at the path named below to e.g. ~/Downloads/:
/Library/Java/JavaVirtualMachines/jdk.1.7.<…>/Contents/
and then replace
<key>JVMCapabilities</key>
<array>
<string>CommandLine</string>
</array>
with the following:
<key>JVMCapabilities</key>
<array>
<string>JNI</string>
<string>BundledApp</string>
<string>WebStart</string>
<string>Applets</string>
<string>CommandLine</string>
</array>

Then restart Mac, and problem solved.

http://stackoverflow.com/questions/19563766/eclipse-kepler-for-os-x-mavericks-request-java-se-6/19594116#19594116

Mac keeps showing popup dialog asking password for Local Items in keychain after upgrading to Mavericks

For those having issue with keychain asking for "Local Items" every time after upgrading to Mavericks, and not being able to unlock the keychain lock (asks again for the same unknown password)

Don't even try to repair (it will not work) or Reset my Default Keychain (it will ask for the password). 

Fixes: Go to ~/Library/Keychain and move all files to the trash. Reboot your mac and keychain should give you a message of error, just click to create new keychain. 

https://discussions.apple.com/message/23496232#23496232