Web app with h2 console to access your database via browser

Here’s a simple war file that deploys H2 database web console along with h2, postgresql and mysql drivers on your web container.

You can access it by simply going to /h2console url and manage your database remotely only with your browser.

No dependencies and no manual steps required, simply deploy and connect to your database.

It’s based on configuration from JBoss quickstart, I’ve only added h2 and other db jars, so it’s ready to be used in any web app container.

Here’s a download link: h2console.war

How to run SolR in maven for tests that need to do some searches

Here’s a Maven pom section that launches Jetty instance with Apache SolR deployed just before tests and stops it after integration tests are finished.
You can select what what war will be deployed and where will be SolR home located (of course you need to prepare it first).
Hope you find it useful:

                                                                                                                       
<plugin>                                                                                                               
    <groupId>org.mortbay.jetty</groupId>                                                                               
    <artifactId>jetty-maven-plugin</artifactId>                                                                        
    <version>8.1.8.v20121106</version>                                                                                 
    <configuration>                                                                                                    
        <!--Need empty war tag so contextHandlers are loaded with Solr on proper path-->                               
        <war></war>                                                                                                    
        <jvmArgs>-Xmx2048m</jvmArgs>                                                                                   
        <systemProperties>                                                                                             
            <systemProperty>                                                                                           
                <name>solr.solr.home</name>                                                                            
                <value>${project.build.directory}/solr</value>                                                         
            </systemProperty>                                                                                          
        </systemProperties>                                                                                            
        <connectors>                                                                                                   
            <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">                           
                <port>8983</port>                                                                                      
            </connector>                                                                                               
        </connectors>                                                                                                  
        <contextHandlers>                                                                                              
            <contextHandler implementation="org.mortbay.jetty.plugin.JettyWebAppContext">                              
                <war>${project.build.directory}/solr-${solr.version}.war</war>                                         
                <contextPath>/solr</contextPath>                                                                       
            </contextHandler>                                                                                          
        </contextHandlers>                                                                                             
    </configuration>                                                                                                   
    <executions>                                                                                                       
        <execution>                                                                                                    
            <id>start-jetty</id>                                                                                       
            <phase>process-test-classes</phase>                                                                        
            <goals>                                                                                                    
                <goal>deploy-war</goal>                                                                                
            </goals>                                                                                                   
            <configuration>                                                                                            
                <scanIntervalSeconds>0</scanIntervalSeconds>                                                           
                <daemon>true</daemon>                                                                                  
                <stopKey>stop</stopKey>                                                                                
                <stopPort>9999</stopPort>                                                                              
            </configuration>                                                                                           
        </execution>                                                                                                   
        <execution>                                                                                                    
            <id>stop-jetty</id>                                                                                        
            <phase>post-integration-test</phase>                                                                       
            <goals>                                                                                                    
                <goal>stop</goal>                                                                                      
            </goals>                                                                                                   
            <configuration>                                                                                            
                <stopKey>stop</stopKey>                                                                                
                <stopPort>9999</stopPort>                                                                              
            </configuration>                                                                                           
        </execution>                                                                                                   
    </executions>                                                                                                      
    <dependencies>                                                                                                     
        <dependency>                                                                                                   
            <groupId>org.eclipse.jetty</groupId>                                                                       
            <artifactId>jetty-rewrite</artifactId>                                                                     
            <version>8.1.8.v20121106</version>                                                                         
        </dependency>                                                                                                  
        <dependency>                                                                                                   
            <groupId>org.slf4j</groupId>                                                                               
            <artifactId>slf4j-log4j12</artifactId>                                                                     
            <version>1.6.1</version>                                                                                   
            <type>jar</type>                                                                                           
        </dependency>                                                                                                  
        <dependency>                                                                                                   
            <groupId>log4j</groupId>                                                                                   
            <artifactId>log4j</artifactId>                                                                             
            <version>1.2.14</version>                                                                                  
            <type>jar</type>                                                                                           
        </dependency>                                                                                                  
    </dependencies>                                                                                                    
</plugin>                                                                                                              

How to use Apache SolR SQL integration and not get hurt

Recently I’ve spent more than one day fixing crazy issues in SolR SQL database integration on my project. You can set everything up using SolR documentation here: http://wiki.apache.org/solr/DataImportHandler. It’s not that difficult and probably is enough to handle data loading for many applications.

We have quite complex query that is feeding SolR with data. It has few sub-selects, group concats etc. We also use SQL database to store original content of documents we’re feeding SolR (so we can recreate index whenever it’s needed). Everything worked fine with simple varchars or integers, but when we wanted to process CLOB/LONGTEXT fields it didn’t work. First for CLOB data SolR was not indexing it’s content, but class name and address of database CLOB handler (i think it was something like org.h2.jdbc.Clob@1c341a for H2 database, oracle.sql.CLOB@24d12a for Oracle). It was Object.toString() call as you probably already guessed and database API was not returning String for CLOB, but some internal representation that SolR should read data from.

Everything should be fixed by using ClobTransformer. Just few changes in data-config.xml and it should be fine… but it wasn’t. I spent quite few hours to find out, that it won’t work if data column you’re feeding ClobTransformer is not written all in uppercase. Yes, it was just that. Adding alias to column name that made it in named in upper case fixed everything.

select col as COLUMN from table

This and sourceColName=”COLUMN” in entity mapping helped. So first advice how to not get hurt is:

Use only upper case names in query result table. Use aliases when needed.

Second issue we had was that after switching database to MySql CLOBs (it’s named LONGTEXT in MySql) again stopped working and again it was some crazy issue nowhere documented. After some time spent in debugger and SolR source I’ve found out that it was not using field name from data-config.xml to map it to schema field, but sourceColName. It also has some logic that was trying to resolve using sourceColName.toLowerCase when it couldn’t match it’s name. I have no idea why it does that way for CLOBs as other fields worked fine. Also switching back to H2 database worked fine. So next advice is:

Use same name as schema field name for query result table columns, but still in upper case. It will keep you safe from first issue described here and work fine because of toLowerCase logic in Solr

Hope it will save you few hours of searching. Will keep posting new crazy things about SolR if I find them.That’s all I have found for now.

Update:

Ok, this is not really true. Done some live debugging in SolR transformers and what you really have to do is use exactly same naming as your database will return.
SolR transformers use Map with table column names (as String in case returned by database) as keys and data as values. So make sure you declare
sourceColNames in mapping in exactly same case as your database returns or map.get() won’t match it.

Alias to open latest log file in Windows Power Shell

Few days ago I’ve posted an alias to open latest log file of your application in bash shell. Same is possible on Windows environment if you use Windows Power Shell command interpreter. What you have to do is edit your profile.ps1 script and add a new function:

set-alias ed "C:/Program Files (x86)/Notepad++/notepad++.exe"
$global:app = "D:/MyApp"
function log {
   $myfile = ls $app/logs/*.log | sort -property lastwritetime | select -last 1
   ed $myfile
}

Of course change value for ed to your favorite editor/log viewer.
Here’s where you can read more about PowerShell profiles:
http://msdn.microsoft.com/en-us/library/bb613488(v=vs.85).aspx

Now just restart shell and execute log command.

File last access time in Java on Linux

Some time ago a friend of mine needed to retrieve last access time of file in his Java code on Linux. Then he used this info to check if some cache files can be removed. I’ve wrote simple JNI based library to do this. It’s very simple but maybe someone can reuse it. So here it is (You need Java 1.4 or newer to use):

Jar with classes: jAccessTimeJ.jar
Native library (32bit): libjAccessTimeC.so

(Sorry no 64bit binary yet. I don’t have 64 bit Linux host right now. Please send it to me if you compile it from sources)

To run:
java -Djava.library.path=./ -cp jAccessTimeJ.jar com.wordpress.jdevel.utils.JAccessTimeUnix /path/to/file

Remember to put .so file in current directory.
Or you could put .so file somewhere on LD_LIBRARY_PATH and then omit -Djava.library.path=./ switch.

To use it from you Java code:

private void testLastAccess() {
    File f = new File("/boot/vmlinuz");
    Date date = JAccessTimeUnix.getLastAccessTime(f);
    System.out.println(date);
}

You can get source from here:
Java-last-access-time-linux

%d bloggers like this: