Groovy script to generate maven repository structure

December 15, 2009 j0hnli Leave a comment

For a project we work with clients who are not working with Maven but deliver jars in our subversion. Since we work with Maven, we need the jars in our repository. Since the amount of libraries were growing and I didn’t want to place the jars manually in the repository, I thought it was time to give groovy scripts a try. I have read ‘Groovy in action’ and it seemed simple enough to try.

Though I am sure the code can be much cleaner and nicer using Groovy syntax, I am still putting my code online. Hopefully it might come in handy for you as well.

The script does the following:
- read a folder where all the jars are checked out
- create a dest folder where the structure will be created
- create the folder structure (jarname/version/jarname-version.jar)
- write the source jars in the same structure
- create pom.xml file for the jar

Next step should be to create a parent project linking all the jars as a package to manage the dependencies and to be able to call mvn deploy. This should deploy the everything automatically to the repository.


import java.util.ArrayList;

import java.io.File;
import java.io.FileWriter;

public class OipServiceTool {
private String sourcefolder;
private String destfolder;
private List list = new ArrayList();

public static void main(String[] args) {
System.out.println("========================================");
System.out.println("============ OipServiceTool ============");
System.out.println("========================================");

OipServiceTool tool = new OipServiceTool();
// set sourcefolder and destfolder
tool.sourcefolder = "/Users/john/Documents/workspace_3.5/ws/OipServices/wsclient-libs";
tool.destfolder = "/Users/john/Documents/workspace_3.5/roo-ws/OipServiceTool/dest";
tool.create();
System.out.println("========================================");
System.out.println("=============== finished ===============");
System.out.println("========================================");
}

public void create() {
File sourceFile = new File(sourcefolder);
if (sourceFile != null && sourceFile.exists() && sourceFile.isDirectory()) {
// run through all libs in webclient-libs
sourceFile.eachFile {
if (it.name.endsWith(".jar")) {
JarFile jarFile = new JarFile(it);
System.out.println("Created jar $jarFile");
list.add jarFile;
}
};
} else {
System.out.println("Source folder is not valid.");
}

File destFile = new File(destfolder);

// - create folder structure
// - create folder with service name
// - create folder with version number
// - copy jar in folder
// - create pom.xml file
def createFolder = {
String pomXML =
"\n" +
"\n" +
"\t4.0.0\n" +
"\tcom.componence.oip.services\n" +
"\t$it.serviceName\n" +
"\t$it.versionNumber\n" +
"\t\n" +
"\t\tcom.componence.oip.services\n" +
"\t\tOipWebservicesParent\n" +
"\t\t1.0\n" +
"\t\n" +
"\t\n" +
"\t\t\n" +
"\t\t\torg.apache.cxf\n" +
"\t\t\tcxf-bundle\n" +
"\t\t\t2.2.3\n" +
"\t\t\n" +
"\t\n" +
"";
String serviceFolder = destFile.getPath() + File.separator + it.serviceName;
String versionFolder = serviceFolder + File.separator + it.versionNumber;
File serviceFile = new File(serviceFolder);
File versionFile = new File(versionFolder);
if (!serviceFile.exists())
serviceFile.mkdir();
if (!versionFile.exists())
versionFile.mkdir();

String jarName = versionFolder + File.separator + it.fileName;
String pomName = versionFolder + File.separator + it.pom;

File jar = new File(jarName);
if (jar.exists()) {
jar.delete();
}

org.apache.commons.io.FileUtils.copyFile(it.file, jar);

if (!it.sources) {
FileWriter fw = new FileWriter(pomName);
fw.write(pomXML);
fw.close();
}
};

if (destFile != null && destFile.exists() && destFile.isDirectory()) {
list.each {createFolder(it)};
}
}

class JarFile {
private String serviceName;
private String versionNumber;
private String fileName;
private File file;
private String pom;
private boolean sources;

public JarFile(File file) throws Exception {
// split the filename '-' sign and check the length
this.file = file;
this.fileName = file.getName();
this.pom = file.getName().replace(".jar", ".pom", ".zip");

String[] nameParts = fileName.split("-");
if (nameParts.length < 1) {
throw new Exception("Name '" + fileName + "' is not supported. Will be ignored.");
}
if ("sources.jar".equals(nameParts[nameParts.length - 1])) {
sources = true;
}
this.versionNumber = nameParts[1].replaceAll(".jar", "");
this.serviceName = nameParts[0];
}

public String toString() {
return "Servicename " + serviceName + "; Version " + versionNumber + "; is source: " + sources;
}
}
}

Categories: Java, Misc Tags: , ,

Weblogic portal 10.2 integration

December 15, 2009 j0hnli Leave a comment

Today have been struggling with Weblogic 10.2 to get a custom authenticator to work. The couple of months I have been working on a Weblogic portal 10.2 project for a large energy supply company. The target was to create a new architecture using WLP as main presentation tier. The business tier is based on ALSB using ESB combined with BPM processes.

The business tier delivers the webservices connector jars which the portal uses to connect to the ALSB. The service connectors are created using Apache CFX, open source webservice framework. All jars provide a single DAO object which is fully unit tested and configurable to either return a mock object or connect to a real server.

The sounds a very good approach untill we tried to finally integrate the services on the client environment. We were not getting any results back from the ALSB though the configurations were all done correctly. The reason was the following:

Weblogic always loads the classes from the parent classloader before it uses the application classloaders. This means that resources provided by the parent classloader will always get precedence. Normally this is not a problem until XML is used. With all the great ideas of SAXParserFactories and DocumentBuilderFactories you basically don’t know what implementation is instanciated to support the factory calls. In weblogic case, the factories are provided in a weblogic specific package located at the parent classloader. Since Apache CFX is heavily using XML, it appears that the weblogic implementations are not compatible with Apache CFX. Though one can argue if Apache CFX is using the libraries wrong or weblogic’s implementation is not quite standard, that is a separate discussion.

For me this was quite a fuzzy problem. Since the issues were not rising on my local environment (as all developers say ;) ). Finally I created a simple JSP file to print out the instances of the xml factories so I could see what the difference was:
Current XML implementations

  • Saxparser factory implementation: <%= SAXParserFactory.newInstance().getClass().getName() %>
  • Saxparser implementation: <%= SAXParserFactory.newInstance().newSAXParser().getClass().getName() %>
  • DomBuilder factory implementation: <%= DocumentBuilderFactory.newInstance().getClass().getName() %>
  • DomBuilder implementation: <%= DocumentBuilderFactory.newInstance().newDocumentBuilder().getClass().getName() %>


To solve this issue, you need to tell Weblogic to use the application class loader for the xml related packages. To do this, you need to add the following changes in the weblogic-application.xml file:

javax.jws.*
org.apache.xerces.*
org.apache.xalan.*


Having this in the weblogic-application.xml file, the classes are loaded from the application classloader. Running the jsp code again now, you will see that the implementation has changed. Of course the packages need to be available in your application libs. In my case, I got the xerces packages as the factory implementations. This solved the webservice integration part for now.

Second part is to integrate the RSA Access Manager to the portal authentication system. To support this, the client has created a custom authentication provider that encapsulates the authentication functionality that is specific for RSA. In the code we can simply use the standard Weblogic authentication api. Now the issue rises that we need to know if the RSA connector could not login the user what the specific exception was. Though the custom authentication provider is throwing typed exceptions, we were not getting them from the server.
After a search we found the following form link:

http://kr.forums.oracle.com/forums/thread.jspa?threadID=794043&tstart=75

This seemed to solve our issue since it was exactly the problem we were facing. We updated the setDomainEnv script with the property added as Java Options for the JVM startup.
%JAVA_OPTIONS% -Dwlp.propogate.login.exception.cause=true

But… as it always goes, we were still getting the same FailedLoginException. Finally it appears that we needed to put the custom authenticator on the first place so it would be the first one that throws an exception. Though by setting the type to ’sufficient’ the custom authenticator was called but the failed login exception was already thrown by the SQLAuthenticator. Since we did see our custom exception in the logs coming back, we didn’t understand why it was not thrown in the controller code. After setting the authenticator to the first row, the exception was thrown as expected.

Both these issues cost me almost a week of full time troubleshooting. So if you have the same issues as I have, I hope this blog entry has saved you some time and frustration ;)

Apache Camel namespaces

June 23, 2009 j0hnli 1 comment

I am running into some weird issues when I integrate Camel 1.6.0 into my Spring project.

The project was started by my 6 months ago or so and I created a prototype complete with junit tests and mock implementations using Camel as main integration framework.

The structure of the project is as follows:

  • Portal frontend (BEA weblogic 10.2)
  • Spring Business layer (POJI & mock implementations & camel based implementations)
  • Integration layer (Camel routing in & out transformations)
  • Multiple endpoints (Webservices, CGI scripts, GET)

After the first proof of concept, the project was taken over by the developers and I was reallocated on a different project. Now all of a sudden, the project doesn’t seem to build anymore. The developer mentioned a schema problem.

I investigated the issue and my initial thought was that the camel-spring.jar was missing from the maven dependencies. Since we use Spring 2, the concepts of spring.handlers and spring.schemas were added so third party libs can ship the XSD files within the library. But of course, this would be too simple of this was the issue.

The dependencies seemed to be ok but I still got errors from eclipse mentioning:

Description    Resource    Path    Location    Type
cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element ‘camelContext’.

When looking into the details, I got the message:

expecting namespace ‘http://activemq.apache.org/camel/schema/spring’ but the target namespace of the schema document is ‘http://camel.apache.org/schema/spring’.

First problem was regarding the fact that camel namespace was not correctly loaded into the spring configurations. So I figured that by solving issue 2, the first would be resolved as well.

As the second problem already defines, the issue arises because camel has recently updated the namespaces to camel.apache.org/schema/spring. The strange thing is that I haven’t updated the dependencies since 1.6 should still be within the same namespace.

Checking the spring.handlers and spring.schemas content of camel-spring.jar, I saw the following content:

========================================================

http\://camel.apache.org/schema/spring=org.apache.camel.spring.handler.CamelNamespaceHandler

========================================================

========================================================

http\://activemq.apache.org/camel/schema/spring/camel-spring.xsd=camel-spring.xsd

http\://activemq.apache.org/camel/schema/spring/camel-spring-1.0.0.xsd=camel-spring.xsd
http\://activemq.apache.org/camel/schema/spring/camel-spring-1.1.0.xsd=camel-spring.xsd
http\://activemq.apache.org/camel/schema/spring/camel-spring-1.2.0.xsd=camel-spring.xsd
http\://activemq.apache.org/camel/schema/spring/camel-spring-1.3.0.xsd=camel-spring.xsd
http\://activemq.apache.org/camel/schema/spring/camel-spring-1.4.0.xsd=camel-spring.xsd
http\://activemq.apache.org/camel/schema/spring/camel-spring-1.5.0.xsd=camel-spring.xsd
http\://activemq.apache.org/camel/schema/spring/camel-spring-1.6.0.xsd=camel-spring.xsd

http\://activemq.apache.org/camel/schema/spring/camel-spring-1.6.1.xsd=camel-spring.xsd

========================================================

The handlers was refering to the Xml handler written for spring integration, the second should map all the xsd files to a classpath resource. In my case this should be refering to ‘camel-spring.xsd’.

I checked the XSD content in the camel-spring jar and in the first line, it shows:

<xs:schema elementFormDefault=”qualified” version=”1.0″ targetNamespace=”http://activemq.apache.org/camel/schema/spring” xmlns:tns=”http://activemq.apache.org/camel/schema/spring” xmlns:xs=”http://www.w3.org/2001/XMLSchema”>

Having walked through multiple articles and forums, I still cannot explain why the problem exists. So basically my current solutions is to switch over the dependencies in maven to Camel version 2.0-M1. Since the xsd and spring properties are all using the same namespace, I have switched over to the new namespace in my configurations and this solved the issue. Though I cna live with the upgrade and a milestone release, I am puzzled what the cause is of the issue. My guess is that somehow, the camel-spring.xsd cannot be found in the classpath and it downloads the file from the public internet, refering to the latest version. This might cause the namespace problem.

But accoring to spring, the spring.schemas should solve this problem. Though I am very annoyed with issue, I decided to leave the matter as I already spent too much time investigating the issue (including blogging about it :) ). You know what caused this issue, let me know. It would really ease my troubled mind :)

Used maven dependencies:
<properties>
<spring.version>2.5.6</spring.version>
</properties>
……………

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>1.6.0</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.1.0</version>
</dependency>

……….

Categories: Java, Spring

Java 1.6 on Mac OS X 1.5

June 22, 2009 j0hnli Leave a comment

I have been using my macbook pro for almost 5 months now and I must say I am very satisfied with the performance. Though the machine gets quite hot when actively used, developing on the Mac is indeed very good.

But………

I find it frustrating that the amount of time that i need to put in for setting up a proper Java development environment takes so much time. There should be better support from Mac for this. But for the time being I will just blog my findings and hopefully someone else finds them usefull.

Environment variables:

As a Java developer, you always need to set the JAVA_HOME environment setting value to the home directory of you Java installation. Though a lot of application nowadays don’t check this variable, Java tools like maven and ant are depending on it. I have added this value on the normal linux way: /etc/profile. By adding this value in profile, the JAVA_HOME is set on startup for all users.

Path:

Second I needed to add the different applications executables to the PATH variable. Normally I always do this in the /etc/profile page. But I found out that for Mac this is done on a different place. In /etc you will find a directory paths.d. In this directory, you can just add a file with some ‘path values’ and it will be automatically added to the path. So this is quite easy. The only think is, you need to know this!

Java versions:

As a developer you need to work on different projects and it often requires us to run different versions of JDK. Normally I don’t have issues with it since I use Eclipse as main IDE. Eclipse installation includes different JDK versions, so you can easily switch it up in Eclipse. But for building purposes (example: running maven in terminal) I often use the terminal to run the build scripts. Now the big husttle is to get Mac use a 1.6 JDK since code depend on it. What I did was the following:

  • install the Mac updates (1.5 update 4)
  • open terminal
  • go to /System/Library/Frameworks/JavaVM.framework/Versions
  • unlink CurrentJDK (it was pointing to 1.5, seen via ln -la)
  • ln -s 1.6 CurrentJDK

Now when I run ‘java -version’, I get the 1.6 64-bit version.

Eclipse memory settings:

Since I run applications in Eclipse that takes quite some memory, I needed to increase the max heapsize of the JVM. Now in Windows, this is done easily by editing the eclipse.ini file. In Mac version, this file seems to be missing. We this is not true. Seems that the executable Eclipse file, can be opened as a directory. The eclipse.ini file, resides insight the eclipse executable.

BEA weblogic

For the ones who are trying to get BEA weblogic running on the Mac. Well, to get the server running was not that big an issue. You need to do some tricks but there are 2 articles written for this purpose. But to get BEA workshop going is a little different story. There is no IDE for this and I haven’t been succesfull in manually installing it. If I have it (or someone get’s it working), I will add comments.

Categories: Java, Mac OS Tags: , , ,