Kohei Nozaki's blog 

Installing CentOS 6.5 into VMware Fusion 6.0.2


Posted on Monday Jan 12, 2015 at 11:45PM in Technology


What are the good points of virtual machines?

I'm working to move my personal financial system which is running on a physical machine to virtual machine because its simplicity of maintenance and portability. currently I'm running the system on tower form PC, but it makes annoying noise, and it consumes power much, so I'm going to make the system virtual, and move it to my old MacBook or something.

Backup of virtual machines are so easy because it exists as regular files in the physical machine, and it can be automated easily thanks to OS X's TimeMachine and VMware Fusion's snapshot. and I can easily move its machine running on in case I need to do it. when I want to do some heavy calculation, I can easily copy the whole of the virtual machine to another high-performance environment anytime while running it on low power-consuming machine regularly.

Installation 

VMware Fusion 6.0.2 supplies "easy installation" function for CentOS 6.5 (not for 7.0). which answers annoying questions instead of me during installation process. all I need to answer were username and password to use. then, VMware will getting almost all of my work done contains installation of VMware Tools. several minutes after, you'll see GUI login prompt. for my purpose GUI is unnecessary but I don't want to do these annoying work by myself so I just followed this way.

I made some changes before installation begins such as following:

  • Increase HDD size to 384GB (There's no need to reserve that actual size in the host machine. actual size increases with actual use in the virtual machine. Increasing of size is impossible when snapshots available, but it's possible after deleting all of snapshots)
  • Increase CPU number to 2
  • Increate amount of memory to 2GB
  • Set network interface to physical (I want to login via ssh from my LAN)
  • Enable VNC daemon

Partitioning that VMware did automatically:

[kyle@localhost ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda3       374G  2.6G  353G   1% /
tmpfs           935M  228K  935M   1% /dev/shm
/dev/sda1       291M   39M  238M  14% /boot

After installation TODOs:

  • Software update (System -> Administration -> Software Update)
  • Add user to sudoers
    su -
    visudo
    then insert following:
    kyle    ALL=(ALL)       NOPASSWD: ALL
  • Change timezone to sync the clock
    sudo cp -p  /usr/share/zoneinfo/Japan /etc/localtime
  • Put your ssh public key to ~/.ssh/authorized_keys (make sure to set the permission of .ssh directory to 700, authorized_keys file to 600. if permission wasn't set correctly, password prompt will be appeared)
I would write more about following procedure such as installation of middleware or database.


How to set default-encoding of Undertow


Posted on Sunday Jan 11, 2015 at 09:57AM in Technology


Launch jboss-cli and connect to WildFly, then enter following and reload:

/subsystem=undertow/servlet-container=default:write-attribute(name=default-encoding,value=UTF-8)
This may solves corruption of multi-byte characters (such as "????") like JSP on Japanese environment or contents. この設定で日本語環境におけるJSPの文字化け等を防げる場合があります.


Debugging Roller's salt processing


Posted on Saturday Jan 10, 2015 at 05:52PM in Technology


Recently I'm getting "javax.servlet.ServletException: Security Violation" 1 or 2 times per day from Roller (the blog engine this blog running on) and lost some unsaved paragraphs every time. I tried to back in such case, Safari and Firefox said the page has expired, and I couldn't take back my unsaved paragraphs. it's annoying so I started to find what the cause is.

Looking at stacktrace and I found that it comes from ValidateSaltFilter, and its related caching classes such as ExpiringLRUCacheFactoryImpl, but it's hard to reproduce, so I added some logging configuration and logging procedure to Roller to acquire more information.

Users can configure log4j which is logging framework Roller used at roller-custom.properties. I added following:

# Appender definition

log4j.appender.roller-debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.roller-debug.File=/Users/kyle/tmp/roller511/rollerdata/roller-debug.log
log4j.appender.roller-debug.layout=org.apache.log4j.PatternLayout
log4j.appender.roller-debug.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss,SSS} %C{1}:%M - %m%n
log4j.appender.roller-debug.Threshold=DEBUG

# Assign loggers to the appender which defined at the preceding.
# log4j.additivity means that stopping propagate to parent logger.

log4j.logger.org.apache.roller.weblogger.util.cache=DEBUG, roller-debug
log4j.additivity.org.apache.roller.weblogger.util.cache=false

log4j.logger.org.apache.roller.weblogger.ui.rendering.util.cache=DEBUG, roller-debug
log4j.additivity.org.apache.roller.weblogger.ui.rendering.util.cache=false

log4j.logger.org.apache.roller.weblogger.ui.core.filters.ValidateSaltFilter=DEBUG, roller-debug
log4j.additivity.org.apache.roller.weblogger.ui.core.filters.ValidateSaltFilter=false
And some debugging procedures are added to ValidateSaltFilter#doFilter() like following:
     public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpReq = (HttpServletRequest) request;

        // note enctype="multipart/form-data" does not send parameters (see
        // ROL-1956) requests of this type are stored in salt.ignored.urls in
        // roller.properties
        if (httpReq.getMethod().equals("POST")
                && !isIgnoredURL(httpReq.getServletPath())) {

            String salt = httpReq.getParameter("salt");
            SaltCache saltCache = SaltCache.getInstance();

            if (log.isDebugEnabled()) {

                try {
                    final Field contentCache = SaltCache.class.getDeclaredField("contentCache");
                    contentCache.setAccessible(true);
                    Object contentCacheValue = contentCache.get(saltCache);
                    
                    final Field cache = LRUCacheImpl.class.getDeclaredField("cache");
                    cache.setAccessible(true);
                    Object cacheValue = cache.get(contentCacheValue);
                    
                    Map cacheMap = (Map) cacheValue;
                    final Set set = cacheMap.keySet();
                    
                    log.debug("Salt which is just received: " + salt);
                    for (Object o : set) {
                        log.debug("Salt in the map: " + o);
                    }
                    
                } catch (NoSuchFieldException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }

                if (salt == null) {
                    log.debug("salt == null");
                }
                else if (saltCache.get(salt) == null) {
                    log.debug("saltCache.get(salt) == null. salt=" + salt);
                }
                else if (saltCache.get(salt).equals(false)) {
                    log.debug("saltCache.get(salt).equals(false). salt=" + salt);
                }
            }

            if (salt == null || saltCache.get(salt) == null
                    || saltCache.get(salt).equals(false)) {

                if (log.isDebugEnabled()) {
                    log.debug("Salt value not found on POST to URL : "
                            + httpReq.getServletPath());
                }

                throw new ServletException("Security Violation");
            }
        }

        chain.doFilter(request, response);
    }

I added all of additional procedures inside if (log.isDebugEnabled()) so I won't need to remove these procedures after investigation. all I need will that just edit roller-custom.properties and reload Roller.

Now I can see how all of salts are creating, removing and be judged which was hit or miss from the log, so I'll take a look it when the problem occurred again.

UPDATE: I think I found the cause. see JIRA.


Installing Apache Derby to WildFly


Posted on Saturday Jan 10, 2015 at 02:29PM in Technology


This post describes how to install Apache Derby 10.11.1.1 as Embedded Server to WildFly 8.2.0.Final. following instructions are intended to use with jboss-cli.

  1. Install jars of Derby as a module into WildFly (assume jar files are located in /tmp)
    module add \
     --name=org.apache.derby \
     --resources=/tmp/derby.jar,/tmp/derbynet.jar,/tmp/derbytools.jar \
     --resource-delimiter=, \
     --dependencies=javax.api,javax.transaction.api
    
  2. Register JDBC Driver named "derby-embedded"
    /subsystem=datasources/jdbc-driver=derby-embedded:add(driver-name=derby-embedded, \
     driver-module-name=org.apache.derby, \
     driver-class-name=org.apache.derby.jdbc.EmbeddedDriver, \
     driver-datasource-class-name=org.apache.derby.jdbc.EmbeddedDataSource, \
     driver-xa-datasource-class-name=org.apache.derby.jdbc.EmbeddedXADataSource)
    
  3. Deploy a MBean which executes the shutdown procedure of Derby
    git clone https://github.com/lbtc-xxx/derby-shutdown-service
    cd derby-shutdown-service; mvn clean package
    cp target/derby-shutdown-service.jar $WILDFLY_HOME/standalone/deployments
    
  4. Define a system property which triggers Derby to listen a port
    /system-property=derby.drda.startNetworkServer:add(value=true)
  5. Define a system property to specify the port Derby will be listening
    /system-property=derby.drda.portNumber:add(value="1527")
  6. Define a system property to specify where log file of Derby will be wrote
    /system-property=derby.stream.error.file:add(value="${jboss.server.log.dir}/derby.log")
  7. Define a system property to append derby.log to exist one
    /system-property=derby.infolog.append:add(value="true")
  8. (For Hibernate user) Add following dependency to modules/system/layers/base/org/hibernate/main/module.xml
    <module name="org.apache.derby"/>
    This prevents following warning:
    WARN  [org.hibernate.dialect.DerbyDialect] (ServerService Thread Pool -- 72) HHH000328: Unable to load/access derby driver class sysinfo to check versions : org.apache.derby.tools.sysinfo from [Module "org.hibernate:main" from local module loader @11028347 (finder: local module finder @14899482 (roots: /Users/kyle/servers/wildfly-8.2.0.Final/modules,/Users/kyle/servers/wildfly-8.2.0.Final/modules/system/layers/base))]
  9. Define a DataSource
  10. For Regular DataSource:

    data-source add \
     --name=DerbyEmbeddedDS \
     --driver-name=derby-embedded \
     --connection-url=jdbc:derby:${jboss.server.base.dir}/derbydata;create=true \
     --jndi-name=java:jboss/jdbc/DerbyEmbeddedDS \
     --user-name=app \
     --password=app
    

    For XA DataSource:

    xa-data-source add \
     --name=DerbyEmbeddedXADS \
     --driver-name=derby-embedded \
     --jndi-name=java:jboss/jdbc/DerbyEmbeddedXADS \
     --user-name=app \
     --password=app \
     --same-rm-override=false \
     --xa-datasource-properties={ \
      "DatabaseName" => "${jboss.server.base.dir}/derbyxadata", \
      "CreateDatabase" => "create"}
    

  11. Test connection
    /subsystem=datasources/data-source=DerbyEmbeddedDS:test-connection-in-pool

Also you need to ensure that shutdown script such as /etc/init.d/wildfly to not execute forcing termination (kill -9) unexpectedly. it will be triggered by exceed timeout of 30 seconds as default and it may bring database corruption in case that executing force shutdown during shutdown process of Derby. I think that longer timeout would be considerable for poor environment.

References


Restarting a stopped job with jberetweb


Posted on Friday Jan 09, 2015 at 09:30PM in jberetweb


Assume that there is a job execution which is STOPPED on the Job Executions table like following. let's see a drop-down list at right end of the row. you can take some actions for each job executions with this "Action" drop-down list.

スクリーンショット 2015-01-09 19.58.29.png

This drop-down list contains some actions like following (for STOPPED one).

スクリーンショット 2015-01-09 19.59.00.png

There are 3 actions available. "Restart" means restarting this execution as a new execution but inherit job instance from previous one. "Abandon" means abandoning this execution as won't be used again. after abandoning, restarting will be impossible. "Re-execute as new instance" means opening "Start Job" window with inheriting both of job name and job parameters of selected instance. also "Stop" is available for running executions.

After selection of Restart, pop-up window will be appeared like following.

スクリーンショット 2015-01-09 20.02.51.png

This window looks similar to "Start Job" window, but Job Name editing is prohibited because this is about to restarting of previous execution. you can edit Job Parameters as well as regular job execution but initial value of them will be inherited if they exists in previous execution.