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

I've written about SQL Developer on quite a few occasions, it's a tool that I use on an almost daily basis. It's improved tremendously over the years that I've been using it and apart from a few minor docking issues I can't find much fault with it...but I really wish it had an easier way to get the custom JDBC connect URL from a database connection. So if you're reading, Jeff Smith - here's a challenge for you - add a new feature that will generate a snippet of Java code from a SQL Developer database connection that will, using JDBC, connect to that database. Meanwhile, for the rest of us lets see how we can get to the JDBC URL as it stands now...

Update: Jeff did respond and I've updated this post with his solution. It can be found at the bottom of this article.

There is actually a partial JDBC URL visible in the Connection Manager already just to the right of the connection name. It's not the entire URL as required by the JDBC driver, but it can get you there if you memorised the rest of the connect string. Call me lazy, but I've never tried to memorise it so I have to refer to documentation for it.
jdbcurl_1.png


We're not done though. SQL Developer does offer the entire custom JDBC URL already...in its connection export file! For that right click on Oracle Connections, click Export Connections... and follow the wizard to generate a JSON file with all the connection details.
jdbcurl_2.png

jdbcurl_3.png

jdbcurl_4.png


Continue reading...  

, , ,

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...  

, , ,