05 Январь, 2010

tomcat datasource native connection

Sometimes need use native db connection.
For example, to correct the following exception:

java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.PoolingDataSource cannot be cast to oracle.jdbc.OracleConnection



private String datasource = "java:comp/env/jdbc/mydb";

private DataSource getDataSource() {
InitialContext ctx;
try {
ctx = new InitialContext();
BasicDataSource ds = (BasicDataSource) ctx.lookup(datasource);
ds.setAccessToUnderlyingConnectionAllowed(true);
return ds;
} catch (NamingException e) {
throw new RuntimeException(e);
}
}

private Connection getNativeConnection(Connection connection) {
return ((DelegatingConnection) connection).getInnermostDelegate();
}

public void doIt() {
Connection connection = null;
try {
connection = getDataSource().getConnection();
Connection nativeConnection = getNativeConnection(connection);
doSomethingWithNativeConnection(nativeConnection);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

}

private void doSomethingWithNativeConnection(Connection connection) {
System.out.println(connection.getClass());
/*- for oracle will be print:
class oracle.jdbc.driver.T4CConnection
*/
// ...
}


For example context.xml below:

<Resource name="jdbc/mydb" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="10" maxWait="10000" username="user" password="password"
driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orasid"
validationQuery="select 1 from dual" />


hibernate sequence generator

ru.olimpiks.MySequenceGenerator.java

public class MySequenceGenerator implements IdentifierGenerator {
public static final String QUERY_NAME = "MySequence.newId";

public Serializable generate(SessionImplementor session, Object object)
throws HibernateException {

Long id = null;
Connection connection = session.connection();

try {
PreparedStatement preparedStatement = connection.prepareStatement(session
.getNamedQuery(QUERY_NAME).getQueryString());

ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
id = resultSet.getLong(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return id;
}
}


hbm.xml

...
<sql-query name="MySequence.newId">
<return-scalar column="id" type="long" />
<![CDATA[
select
seq_my.NEXTVAL id
from
dual
]]>
</sql-query>
...


ru.olimpiks.MyEntity.java

@Entity
@Table(name = "MY_TABLE")
public class MyEntity implements java.io.Serializable {

private Long id;

@Id
@Column(name = "ID")
@GeneratedValue(generator = "my_id")
@GenericGenerator(name = "my_id", strategy = "ru.olimpiks.MySequenceGenerator")
public Long getId() {
return this.id;
}

public void setId(Long id) {
this.id = id;
}
// ...
}

02 Январь, 2010

oracle type to java beans with jaxb

  1. create oracle types
  2. oracle type to xsd
  3. xsd to java beans
  4. oracle type to java object with jaxb



1. create oracle types



CREATE OR REPLACE TYPE qwerty_element_t AS OBJECT
(str VARCHAR2(10)
,num number
,str_big clob
,dt date
);
/
CREATE OR REPLACE TYPE qwerty_tt AS TABLE OF qwerty_element_t;
/
CREATE OR REPLACE TYPE qwerty_t AS OBJECT
(id VARCHAR2(1000)
,element qwerty_element_t
,elements qwerty_tt
);
/
create or replace
function getQwertyAsXml(p_id varchar2) return clob as
v_qwerty qwerty_t;
v_xml XMLTYPE;
begin
-- init object instance
v_qwerty := ...;
--convert object to xml
v_xml := XMLTYPE (v_qwerty);
-- xml to clob
return v_xml.getClobVal();
end;
/


2. oracle type to xsd



OracleType2XSD.groovy

class OracleType2XSD {
static String clob2String(java.sql.Clob clob) {/*...*/}
static Sql getSql() {/*...*/}
static String oracleType2XSD(Sql sql, String oracleType, String rootTag) {
String res
sql.call("""{ ${Sql.CLOB} = call dbms_xmlschema.generateSchema(
user,
${Sql.VARCHAR(oracleType)},
${Sql.VARCHAR(rootTag)},
TRUE,FALSE,TRUE
).getClobVal() }""") { xsd ->
res = clob2String(xsd)
}
res
}
static void main(args) {
new File('qwerty.xsd').withWriter {
it << oracleType2XSD(getSql(), 'QWERTY_T', 'qwerty')
}
}
}

execute

set CLASSPATH=...
java -cp %CLASSPATH% groovy.lang.GroovyShell OracleType2XSD.groovy

product qwerty.xsd

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xdb="http://xmlns.oracle.com/xdb"
xsi:schemaLocation="http://xmlns.oracle.com/xdb http://xmlns.oracle.com/xdb/XDBSchema.xsd">
<xsd:element name="qwerty" type="QWERTY_TType" />
<xsd:complexType name="QWERTY_TType">
<xsd:sequence>
<xsd:element name="ID">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="1000" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="INNER" type="QWERTY_INNER_TType" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="QWERTY_INNER_TType">
<xsd:sequence>
<xsd:element name="STR">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="10" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="NUM" type="xsd:double" />
<xsd:element name="STR_BIG" type="xsd:string" />
<xsd:element name="DT" type="xsd:date" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>


3. xsd to java beans



execute

%JAVA_HOME%/bin/xjc qwerty.xsd -p ru.olimpiks.oracle.model

product java beans:

ru.olimpiks.oracle.model.QWERTYELEMENTTType.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "QWERTY_ELEMENT_TType", propOrder = {
"str",
"num",
"strbig",
"dt"
})
public class QWERTYELEMENTTType {
@XmlElement(name = "STR", required = true)
protected String str;
@XmlElement(name = "NUM")
protected double num;
@XmlElement(name = "STR_BIG", required = true)
protected String strbig;
@XmlElement(name = "DT", required = true)
@XmlSchemaType(name = "date")
protected XMLGregorianCalendar dt;
//...setters and getters
}

ru.olimpiks.oracle.model.QWERTYTType.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "QWERTY_TType", propOrder = {
"id",
"element",
"elements"
})
@XmlRootElement(name="qwerty")//!!!to further correct unmarshall object, you must add this line
public class QWERTYTType {
@XmlElement(name = "ID", required = true)
protected String id;
@XmlElement(name = "ELEMENT", required = true)
protected QWERTYELEMENTTType element;
@XmlElement(name = "ELEMENTS")
protected List<QWERTYELEMENTTType> elements;
//...setters and getters
}


4. oracle type to java object with jaxb (groovy example)



static QWERTYTType getQwerty(Sql sql, String id) {
String res
sql.call("""{ ${Sql.CLOB} = call getQwertyAsXml(${Sql.VARCHAR(id)}) }""") { p_res ->
res = clob2String(p_res)
}
JAXBContext context = JAXBContext.newInstance(QWERTYTType.class);
Unmarshaller u = context.createUnmarshaller();
return (QWERTYTType)u.unmarshal(new java.io.StringReader(res));
}


Can't register Tomcat as Windows service on some computers, under Java6

source...

jdk1.6.0_12
apache-tomcat-6.0.20
Windows Server 2003 R2


...
[2009-12-15 19:05:16] [info] Procrun (2.0.4.0) started
[2009-12-15 19:05:16] [info] Running Service...
[2009-12-15 19:05:16] [info] Starting service...
[2009-12-15 19:05:16] [174 javajni.c] [error] The specified module could not be found.
[2009-12-15 19:05:16] [994 prunsrv.c] [error] Failed creating java d:\dev\jdk1.6.0_12\jre\bin\server\jvm.dll
[2009-12-15 19:05:16] [1269 prunsrv.c] [error] ServiceStart returned 1
[2009-12-15 19:05:16] [info] Run service finished.
[2009-12-15 19:05:16] [info] Procrun finished.
...


For fix it:

copy %JAVA_HOME%/bin/msvcr71.dll %CATALINA_HOME%/bin

22 Ноябрь, 2009

syntax highlighter

Источник.

Для подсветки синтаксиса можно использовать SyntaxHighlighter, который поддерживает различные языки и темы.


Добавим в <head> тег нашего html шаблона следующее:

<!-- Add-in CSS for syntax highlighting -->
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/2.1.364/styles/shThemeRDark.css' rel='stylesheet' type='text/css'/>
<!-- Add-in Script for syntax highlighting -->
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shCore.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushAS3.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushColdFusion.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushErlang.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushJavaFX.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushPowerShell.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/2.1.364/scripts/shBrushXml.js' type='text/javascript'/>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/2.1.364/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
<!-- End code hilight -->


Использовать данную библиотеку можно следующим образом.

Используя специальный тег <script> с окаймлением CDATA:

<script type="syntaxhighlighter" class="brush: html"><![CDATA[
<html>
<head>
<title>Carter Tomorrow Fund Donations</title>
<meta name="title" content="Help Give to the Carter Tomorrow Fund" />
<meta name="description" content="Show your support and help out with a small gift"
]]></script>

или при помощи тега <pre> с символами экранированными для html:


<pre class="brush: html">
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Carter Tomorrow Fund Donations&lt;/title&gt;
&lt;meta name="title" content="Help Give to the Carter Tomorrow Fund" /&gt;
&lt;meta name="description" content="Show your support and help out with a small gift"
</pre>


17 Ноябрь, 2009

family

-Что нужно чтобы быть счастливыми родителями?
-Чувство юмора!

из какой-то книги...

16 Ноябрь, 2009

tomcat and log4j

http://tomcat.apache.org/tomcat-6.0-doc/logging.html
http://wiki.apache.org/logging-log4j/Log4jXmlFormat

  1. Create a file called log4j.xml or log4j.properties and save it into $CATALINA_HOME/lib
  2. Download Log4J (v1.2 or later) and place the log4j jar in $CATALINA_HOME/lib
  3. Download the additional logging components. See the extras components documentation for details - http://tomcat.apache.org/tomcat-6.0-doc/extras.html - (http://www.sai.msu.su/apache/tomcat/tomcat-6/v6.0.20/bin/extras/tomcat-juli.jar,
  4. http://www.sai.msu.su/apache/tomcat/tomcat-6/v6.0.20/bin/extras/tomcat-juli-adapters.jar)
  5. Replace $CATALINA_HOME/bin/tomcat-juli.jar with extras/tomcat-juli.jar.
  6. Place extras/tomcat-juli-adapters.jar in $CATALINA_HOME/lib.
  7. Start Tomcat





log4j.xml


log4j.properties

#log4j.rootLogger=debug, stdout, R, E
log4j.rootLogger=info, stdout, R, E

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.target=System.out
log4j.appender.stdout.encoding=UTF-8
log4j.appender.stdout.MaxBackupIndex=10
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%c] - %m%n

log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${catalina.home}/logs/tomcat.log
log4j.appender.R.encoding=UTF-8
log4j.appender.R.MaxFileSize=20MB
log4j.appender.R.MaxBackupIndex=50
#log4j.appender.R.appender=true
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c{1}] - %m%n

log4j.appender.E=org.apache.log4j.RollingFileAppender
log4j.appender.E.File=${catalina.home}/logs/error.log
log4j.appender.E.encoding=UTF-8
log4j.appender.E.Threshold = error
log4j.appender.E.MaxFileSize=10MB
log4j.appender.E.MaxBackupIndex=10
#log4j.appender.E.appender=true
log4j.appender.E.layout=org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern=%d %-5p [%t] [%c{1}] - %m%n

log4j.logger.org.apache.catalina=info, R
#log4j.logger.org.apache.catalina.core=DEBUG, R
#log4j.logger.org.apache.catalina.session=DEBUG, R


Tomcat 6 defines loggers by Engine and Host names. For example, for a default Catalina localhost log.

log4j.logger.org.apache.catalina.core.ContainerBase.[Catalina].[localhost]=DEBUG, R

Note that there are known issues with using this naming convention (with square brackets) in log4j XML based configuration files, so we recommend you use a properties file as described until a future version of log4j allows this convention.

groovy sql


def sql(url,user,passqord,driver,yield){
Sql s = Sql.newInstance(url, user, password, driver)
s.connection.autoCommit = false
try {
yield(s)
s.commit()
}
catch (Exception e) {
s.rollback()
throw e
}
finally {
s?.connection.close()
}
}



def connectionString = '::'
sql("jdbc:oracle:thin:@${connectionString}",'user', 'password','oracle.jdbc.OracleDriver') { sql ->
sql.execute("insert into qwerty(id,field1,field2) values(my_seq.nextval,?,?)",[val2,val3])

sql.eachRow("select * from my_table") { println it }
sql.eachRow("select * from my_table") { println it.field1 }

def values = []
values << Sql.DATE(new java.sql.Date(System.currentTimeMillis()))
values << Sql.TIME(new java.sql.Date(System.currentTimeMillis()))
values << Sql.TIMESTAMP(new java.sql.Timestamp(System.currentTimeMillis()))
values << 'long string'
values << Sql.DECIMAL //add out parameter
long id;
sql.call("""begin
insert into qwerty(id,field_date,field_date,field_time,field_timestamp,field_clob) values(my_seq.nextval,?,?,?,?) return id into ?;
end;""",values) {
id = it
println "id = ${id}"
}

def str = """call my_package.my_procedure(
? /*p_param1 in number*/
,? /*p_param2 in out number*/
,? /*p_param3 varchar2*/
)""".replaceAll(/\s+/, ' ')
def params = [
123 /*p_param1 in number*/
,Sql.inout(Sql.DECIMAL(null)) /*p_param2 in out number*/
,'my string' /*p_param3 varchar2*/
]
println "param in out befor call = ${params[1]}"
sql.call(str, params)
println "param in out after call = ${params[1]}"
}


//generate ddl script for insert
def insertRowDDL(tableName, fieldsMap) {
def into = fieldsMap.keySet().toList().join(',')
def str = (["?,"]*fieldsMap.size()).join()[0..-2]
str = "insert into ${tableName}(${into}) values(${str})"
}


//create row and get id, if id auto generated by trigger, for example
def createRowAndGetId(Sql sql, tableName, fieldsMap, idFieldName) {
def str = insertRowDDL(tableName, fieldsMap)
def values = fieldsMap.values().toList()
values << Sql.DECIMAL //add out parameter
str = """begin
${str} return ${idFieldName} into ?;
end;"""
long res = 0;
try {
sql.call(str,values) { res = it }
} finally { }
return res
}


def fieldsMap = [:]
fieldsMap.field1=val1
fieldsMap.field2=val2
fieldsMap.field_time=Sql.TIME(new java.sql.Date(System.currentTimeMillis()))
fieldsMap.field_clob='long string'
println createRowAndGetId(sql, 'qwerty', fieldsMap, 'id')


23 Октябрь, 2009

run groovy script with java only

Для запуска groovy скриптов используя только java, без groovy дистрибутива - делаем следующее:

Структура рабочего проекта:
src - папка со скриптами groovy
lib - необходимые библиотеки
env.bat - подключение окружения
run.bat - запуск скриптов

в папке lib необходимо наличие - groovy-all-1.6.0.jar!!!

env.bat

echo off
set CUR_DIR=%~dp0
rem set JAVA_HOME=%CUR_DIR%jdk1.6.0_12
rem set PATH=%JAVA_HOME%/bin;%PATH%
set LIB_DIR=%CUR_DIR%lib
set CLASSPATH=%LIB_DIR%\groovy-all-1.6.0.jar;%CLASSPATH%
set CLASSPATH=%LIB_DIR%\log4j-1.2.15.jar;%CLASSPATH%
set CLASSPATH=%LIB_DIR%\nekohtml.jar;%CLASSPATH%
set CLASSPATH=%LIB_DIR%\ojdbc6.jar;%CLASSPATH%
set CLASSPATH=%LIB_DIR%\xercesImpl.jar;%CLASSPATH%
set JAVA_OPTS=-Xms256m -Xmx528m -XX:MaxPermSize=256m %JAVA_OPTS%
set JAVA_OPTS=-Dgroovy.source.encoding=UTF8 %JAVA_OPTS%
set JAVA_OPTS=-Dfile.encoding=UTF-8 %JAVA_OPTS%


run.bat

call %~dp0env.bat
set SCRIPT_HOME=%~dp0src
set MAIN_SCRIPT=%SCRIPT_HOME%/Main.groovy
call java -cp %CLASSPATH%;%SCRIPT_HOME% groovy.lang.GroovyShell %MAIN_SCRIPT% %*

07 Август, 2009

Сжимаем virtualbox disk image

После продолжительной работы с гостевой операционкой ее образ может сильно распухнуть. Для исправления этого недоразумения делаем так:

1. обнуляем все свободные блоки жесткого диска в гостевой ос, для чего в ней запускаем команду sdelete


sdelete -c

2. затем необходимо сжать образ из хостовой ос командой

VBoxManage modifyhd winxp.vdi compact

У меня образ в 9гб ужался в 3гб!