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.jar
into$CATALINA_HOME/lib
-
Define a
Resource
element insideContext
element in$CATALINA_HOME/conf/context.xml
as 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 package
and puttarget/derby-shutdown-listener.jar
into$CATALINA_HOME/lib
-
Put following fragment into
Server
element in$CATALINA_HOME/conf/server.xml
<Listener className="org.nailedtothex.derby.DerbyShutdownLifecycleListener" />
Test of lookup from Servlet
-
Put following fragment into
WEB-INF/web.xml
of 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/