Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

No matter how good official documentation is, sometimes it simply isn't enough to cover certain cases when multiple technologies overlap, and sometimes small mistakes creep in too. So some time ago while I was working on a WS-AtomicTransaction enabled webservice, I ran into issues that were to do with WebLogic dependencies and compilation. At the time I got past the issues with what were essentially hacks, where I used deeply nested dependencies in Maven, but now I wanted to revisit this approach and to see what was required to build a WS-AT enabled webservice from scratch by using only documented approaches.

This post builds heavily on the article I wrote a couple of years ago where I show an example JAX-WS webservice built with the Oracle WebLogic Maven Plugin. It also depends on another post from earlier this year where I wrote about setting up a WebLogic development server. So check those out if something is not clear here.

The basic requirement is that you have a WebLogic 12.2.1.3 development server set up. In my case since I use a Mac, the path to the ORACLE_HOME for this server is /Applications/devtools/wls_12.2.1.3. Adjust it to suit your needs and your setup.

So the WS-AT topic is rather large for one post, but there are no tricks or magic to writing the Java code for a WS-AT participant service i.e. a service that joins a distributed transaction that is initiated by another (coordinating) service. All you need to do is simply add the weblogic.wsee.wstx.wsat.Transactional annotation to the service class or individual web methods and then have the correct dependencies to compile it. Lets look at the Java side first. In fact, this is mostly lifted verbatim from the official documentation.
 Java
package net.igorkromin;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.BindingType;
import weblogic.wsee.wstx.wsat.Transactional;
@WebService(
name="WsAtExamplePortType",
portName="WsAtExamplePort",
serviceName="WsAtExampleService",
targetNamespace="http://igorkromin.net/wsat/participant"
)
@SOAPBinding(
style=SOAPBinding.Style.DOCUMENT,
use=SOAPBinding.Use.LITERAL,
parameterStyle=SOAPBinding.ParameterStyle.WRAPPED
)
@BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
public class WsAtExampleImpl {
public WsAtExampleImpl() {
super();
}
@WebMethod()
@Transactional(
version=Transactional.Version.WSAT12,
value=Transactional.TransactionFlowType.MANDATORY
)
public void doOp()
{
/*
Your Code Here - All transactional resources with which the code
interacts are enlisted with the imported transaction.
*/
}
}


Continue reading...  

, , , , ,

The Metal Earth Penny-Farthing kit comes from the miscellaneous collection. For me it definitely was a kit that stood out on its own, without any similar theme to the rest of the kits I've built. However, it had its unique quirks and didn't take long to build, so it's an interesting kit to consider.
IMG_1398.jpg


This kit had two sheets of laser cut metal, which was expected given how large some of the wheel pieces were. There were quite a few redundant pieces left in the end as well - I guess those sheets had to be filled with something. One complaint I had about instructions for this kit was that same type of pieces were not coloured the same in the instruction booklet like they are on other kits. There was a nice touch on the packaging though - the design of a Penny-Farthing was described on the back with a little historical blurb to go along with it.

IMG_1384.jpg IMG_1385.jpg


The smaller wheel was first to be assembled. Those pieces were very delicate, each of the spokes was extremely thin and easy to bend out of shape. In the end the two parts came together to make the full wheel with a rim/tyre portion.

IMG_1386.jpg IMG_1387.jpg


The frame was next. It didn't have a lot of pieces and the small wheel attached to it as a permanent fixture. As expected from a Metal Earth kit, the wheel didn't spin.

IMG_1388.jpg IMG_1389.jpg


Continue reading...  

,

Recently I've been working with a PL/SQL package that used DBMS_OUTPUT to generate a report. This report was then copy/pasted into a small Java utility I wrote, which parsed it and generated a visual representation of the report data. Because this didn't need to be automated, I was calling the package manually using SQL Developer. Now that work is over, I started thinking if the Java utility could have been enhanced to capture the report itself.

So in my spare time I decided to write a utility class that would let me capture DBMS_OUTPUT lines in case I wanted to do something like this in the future. This isn't exactly new and has been covered here and on Ask Tom, however I didn't like either of those approaches. I wanted my utility class to work with try-with-resources so that I wouldn't have to write any boring boiler plate code when using this utility.

This is what I came up with...
 Java
package net.igorkromin;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class DbmsOutputCapture implements AutoCloseable {
private int captureLines = 1024;
private CallableStatement enableStmt;
private CallableStatement readLineStmt;
private CallableStatement disableStmt;
public DbmsOutputCapture(Connection dbConn) throws SQLException {
enableStmt = dbConn.prepareCall("begin dbms_output.enable(NULL); end;");
disableStmt = dbConn.prepareCall("begin dbms_output.disable(); end;");
readLineStmt = dbConn.prepareCall("begin dbms_output.get_lines(?, ?); end;");
readLineStmt.registerOutParameter(1, Types.ARRAY,"DBMSOUTPUT_LINESARRAY");
readLineStmt.registerOutParameter(2, Types.INTEGER,"INTEGER");
readLineStmt.setInt(2, captureLines);
}
public DbmsOutputCapture(Connection dbConn, int captureLines) throws SQLException {
this(dbConn);
this.captureLines = captureLines;
}
public List<String> execute(CallableStatement userCall) throws SQLException {
List<String> retLines = new ArrayList<>();
try {
enableStmt.executeUpdate();
userCall.execute();
int fetchedLines;
do {
readLineStmt.execute();
fetchedLines = readLineStmt.getInt(2);
Array array = null;
try {
array = readLineStmt.getArray(1);
String[] lines = (String[]) array.getArray();
/* loop over number of returned lines, not array size */
for (int i = 0; i < fetchedLines; i++) {
String line = lines[i];
retLines.add(line != null ? line : "");
}
}
finally {
if (array != null) {
array.free();
}
}
} while(fetchedLines == captureLines);
}
finally {
disableStmt.execute();
}
return retLines;
}
@Override
public void close() throws SQLException {
if (!quietClose(enableStmt, readLineStmt, disableStmt)) {
throw new SQLException("Could not close all callable statements");
}
}
private boolean quietClose(CallableStatement ... callableStatements) {
boolean allSuccess = true;
for (CallableStatement stmt : callableStatements) {
try {
stmt.close();
}
catch (SQLException e) {
allSuccess = false;
}
}
return allSuccess;
}
}


Continue reading...  

, , ,

sadface2.png
It must be that time of the year that Amazon's vampires, err, I mean recruiters awaken, come out of the woodwork and try to gather new initiates. Indeed it is very fitting that this is happening around Halloween! Two years ago, after a rather unpleasant interview process, I asked to be put on a do-not-contact register so I thought that I'd never have to hear from an Amazonian again, yet just like in the plot of Groundhog Day, here I am reading yet another email from an Amazon recruiter asking to talk to me about a possible opportunity. Will this horror never end?

Since Amazon promised to follow up on my experience but never did, I figured this would be a perfect time to share it. This is a story of my Amazon recruitment experience. I wish I could say it was a pleasant one but sadly it neither had a happy ending nor a smooth journey. This is a retelling of the two tedious months that Amazon put me through only to tell me that I can't code, which I now find funny, but at the time it was rather insulting and humiliating considering that programming is a big part of my job and, at least in my opinion, I'm not all that bad at it.

Update: Thanks for everyone reading this, I really didn't expect such a huge interest in my story. Based on some comments I read it seems to me that the light-hearted humour nature of this post was missed by some. This post fits into my weekend/fun post, so parts are a little dramatic, but that's the fun in writing this. Enjoy reading the rest of the article!

Background

I work in the integration/services space and have to write a large amount of custom code (Java, SQL, Bash, etc) to make products work together. It's not 'pure' engineering because it involves a good deal of customer interaction, requirements analysis, design work, expectation management, putting out fires and some people management. So typically whenever I'd receive a recruitment email from Amazon, it would go straight to trash because the jobs didn't really line up with what I wanted to do...until one day I had a crazy idea about going back into engineering. I had a colleague whom I worked with previously who worked at Amazon locally, so I went out for some drinks with the team to meet them, see what it was like and to decide whether I wanted to apply. It could have been a drunken decision but I went ahead with the application.

Initial response

I sent in my resume and received a response from the recruiter the next day. They wanted to start the interviewing/recruitment process immediately. Naturally I was excited to get started so missed some of the obvious red flags here. The recruiter was in a different country (in fact a different continent) to me. From their responses, they either didn't know how to convert for time zones or really didn't care (outside of US didn't seem to exist for this recruiter). After several attempts of incompatible meeting time suggestions, two weeks later we were finally able to schedule an introduction call. I was surprised how little regard the recruiter had for the 17 hour difference in time zones and the fact that I have a full time job.

I was still looking forward to the call though!

Continue reading...  

,