public static <T> T doLookup(String name) throws NamingException {
return (T) (new InitialContext()).lookup(name);
}
Doesn't InitialContext.doLookup() bring resource leak?
TweetPosted on Thursday Feb 12, 2015 at 12:00PM in Technology
There’s a convenient static method called InitialContext.doLookup() which introduced at Java6. it uses Generics so we don’t need to cast returned object by hand. implementation is very simple as follows:
I think it’s bad because there’s no way to invoke InitialContext#close() because doLookup() doesn’t save the reference to InitialContext instance anywhere. if it acquired some resource such as TCP socket it may brings resource leak.
Personally I will avoid use of doLookup() because of this reason while there are many opinion that it doesn’t need to close explicitly at most of environments. I guess I’m too sensitive about it but I have a history of strugging with leak of JDBC resources (Connection, Statement and ResultSet) so I’m very curious about this kind of problem.
Sometimes handling of InitialContext is annoying because it should be keep opened during use of returned instance on some environments or implementations. also I wonder why InitialContext doesn’t implemented AutoCloseable while it’s a perfect candidate for it.
For Servlets you could write as follows:
public class TestServlet extends HttpServlet {
private Context context;
private DataSource dataSource;
@Override
public void init() throws ServletException {
try {
context = new InitialContext();
dataSource = (DataSource) context.lookup("java:comp/env/jdbc/derby");
} catch (NamingException e) {
throw new ServletException(e);
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try (Connection cn = dataSource.getConnection()) {
// database operations
} catch (SQLException e) {
throw new ServletException(e);
}
}
@Override
public void destroy() {
if (context != null) {
try {
context.close();
} catch (NamingException e) {
// no-op
}
}
}
}
In jberetweb, I wrote an interface named JobOperatorWork and a method intended to use with it called doWorkWithJobOperator() for ease of handling of InitialContext closing.
In Java EE environment, you could simply use @Resource or @EJB for avoiding annoying procedure of closing.
Tags: javaee
jconsole.sh in WildFly 8.2.0.Final doesn't work
TweetPosted on Thursday Feb 12, 2015 at 10:06AM in Technology
Environment
-
WildFly 8.2.0.Final
Problem
A shell script $WILDFLY_HOME/bin/jconsole.sh is shipped with WildFly to launch JConsole with an additional jar to connect to WildFly instance, but it doesn’t work. as reported in this issue, it made wrong classpath.
Workaround
Launch $JAVA_HOME/bin/jconsole directly instead with an additional parameter as follows:
jconsole -J-Djava.class.path=$JAVA_HOME/lib/jconsole.jar:$JAVA_HOME/lib/tools.jar:/Users/kyle/servers/wildfly-8.2.0.Final/bin/client/jboss-cli-client.jar
Defining Embedded Derby as a DataSource of Tomcat 8
TweetPosted on Wednesday Feb 11, 2015 at 12:16AM in Technology
Configuration
-
Put
derby.jarinto$CATALINA_HOME/lib -
Define a
Resourceelement insideContextelement in$CATALINA_HOME/conf/context.xmlas follows:<Resource name="jdbc/derby" auth="Container" driverClassName="org.apache.derby.jdbc.EmbeddedDriver" username="sa" password="sa" type="javax.sql.DataSource" url="jdbc:derby:/Users/kyle/tmp/sampledb;create=true"/>
-
Clone derby-shutdown-listener, exec
mvn clean packageand puttarget/derby-shutdown-listener.jarinto$CATALINA_HOME/lib -
Put following fragment into
Serverelement in$CATALINA_HOME/conf/server.xml<Listener className="org.nailedtothex.derby.DerbyShutdownLifecycleListener" />
Test of lookup from Servlet
-
Put following fragment into
WEB-INF/web.xmlof your web application<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <resource-ref> <res-ref-name>jdbc/derby</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app> -
Put an example Servlet as follows
@WebServlet(urlPatterns = "/") public class TestServlet extends HttpServlet { private Context context; private DataSource dataSource; @Override public void init() throws ServletException { try { context = new InitialContext(); dataSource = (DataSource) context.lookup("java:comp/env/jdbc/derby"); } catch (NamingException e) { throw new ServletException(e); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try (Connection cn = dataSource.getConnection(); Statement st = cn.createStatement(); ResultSet rs = st.executeQuery("SELECT CURRENT_TIMESTAMP FROM SYSIBM.SYSDUMMY1")) { while (rs.next()) { resp.getWriter().write(rs.getTimestamp(1).toString()); } } catch (SQLException e) { throw new ServletException(e); } } @Override public void destroy() { if (context != null) { try { context.close(); } catch (NamingException e) { // no-op } } } } -
Access from your browser
Complex string replacing on Java
TweetPosted on Tuesday Feb 10, 2015 at 10:06PM in Technology
Sometimes annoying requirement of string replacing will risen. everytime I forgotten how to do it so I leave this as my note. also there’s a JUnit test case.
Requirement
Assume we have following string literals. we have to convert input string to expected.
String input = "<li><a href=\"../../jbatch/hello/\" >anchor</a></li>"; String expected = "<li><a href=\"/entry/articles-jbatch-hello\" >anchor</a></li>";
Solutions
Using numbered groups
Pattern p = Pattern.compile("(<a href=\")\\.\\./\\.\\./(.*)/(.*)/\"");
Matcher matcher = p.matcher(input);
String result = matcher.replaceAll("$1/entry/articles-$2-$3\"");
Using named groups
Pattern p = Pattern.compile("(?<prefix><a href=\")\\.\\./\\.\\./(?<category>.*)/(?<handle>.*)/\"");
Matcher matcher = p.matcher(input);
String result = matcher.replaceAll("${prefix}/entry/articles-${category}-${handle}\"");
Using Matcher#appendReplacement(). this one is most flexible.
Pattern p = Pattern.compile("(?<prefix><a href=\")(?<url>.*)\"");
Matcher matcher = p.matcher(input);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
// any complex logic can be placed here
String url = matcher.group("url");
String[] urls = url.split("/");
matcher.appendReplacement(sb, "${prefix}/entry/articles-" + urls[2] + "-" + urls[3] + "\"");
}
matcher.appendTail(sb);
String result = sb.toString();
Escaping special character for replacement
$ have special meaning for replacement string, but sometimes we may need to use $ as just a literal. for such case, we can use Matcher.quoteReplacement() for escaping $ character as follows:
String input = "../../jbatch/hello/";
String expected = "../../$1/${name}/";
Pattern p = Pattern.compile("(?<prefix>\\.\\./\\.\\.)/.*/.*/");
String result = p.matcher(input).replaceAll("${prefix}/" + Matcher.quoteReplacement("$1/${name}") + "/");
Tags: regex
Enabling SSL for Apache/WildFly
TweetPosted on Monday Feb 09, 2015 at 05:56PM in Technology
Environment
-
WildFly 8.2.0.Final
-
httpd-2.2.15-39.el6.centos.x86_64
-
CentOS 6.5
Put SSL related files
-
public.crt: begins with
BEGIN CERTIFICATE -
intermediate.crt: begins with
BEGIN CERTIFICATE -
private.key: begins with
BEGIN RSA PRIVATE KEY
Edit /etc/httpd/conf.d/ssl.conf
SSLEngine on SSLProtocol all -SSLv2 -SSLv3 SSLCertificateFile /usr/local/ssl/public.crt SSLCertificateKeyFile /usr/local/ssl/private.key SSLCertificateChainFile /usr/local/ssl/intermediate.crt SSLPassPhraseDialog exec:/usr/local/ssl/passphrase.sh
Put passphrase.sh
#!/bin/sh echo "put the passphrase here"
Define an ajp-listener
Execute following command with jboss-cli:
/socket-binding-group=standard-sockets/socket-binding=https-external:add(port=443) /subsystem=undertow/server=default-server/ajp-listener=myListener:add(socket-binding=ajp, redirect-socket="https-external", enabled=true)
Put /etc/httpd/conf.d/jk.conf
<VirtualHost *:80> ProxyPass / ajp://localhost:8009/ ProxyPassReverse / http://www.example.org/ </VirtualHost>
Put following inside VirtualHost element of /etc/httpd/conf.d/ssl.conf
ProxyPass / ajp://localhost:8009/ ProxyPassReverse / https://www.example.org/
