计划把公司应用后台的数据库服务也统一迁移到docker上,因此起了在docker上部署Oracle数据库的念头。记得以前在docker hub上看到过现成的数据库image,上去一搜,发现不是版本太低就是说被O记要求删除。既然是这样,那O记官方有没以支持呢?放狗一搜,发现O记官方在github上有专门的docker images项目,包含了Java、数据库、应用等等的镜像生成文件。就算是自己生成镜像文件,这些资料也对写Dockerfile很有参考价值。

在github上下载Oracle数据库的docker文件,在OTN下载好Oracle Database 12C的安装包,把zip文件置于OracleDatabase/dockerfiles/12.0.0.2目录下,然后开始Oracle数据库docker的无脑安装 。

1.运行dockerfiles下的buildDockerImage.sh命令

从Oracle Linux的slim-7版本生成数据库镜像文件,该命令支持生成Oracle数据库企业版、标准版和XE版本。俺使用的是企业版。


# ./buildDockerImage.sh -v 12.1.0.2 -e -i

该脚本命令参数说明如下:

-v: version to build
Choose one of: 11.2.0.2 12.1.0.2
-e: creates image based on 'Enterprise Edition'
-s: creates image based on 'Standard Edition 2'
-x: creates image based on 'Express Edition'
-i: ignores the MD5 checksums

开始配置环境,复制安装文件,静默安装数据库,最后生成镜像。大概需要10来分钟时间。

[highlight dark=”no”]注:在生成数据库镜像前,请特别留意Docker的存储驱动配置必须btrfs或overlay2,如果使用aufs在生成过程中会出现各种问题,俺还特意在github上特意开了issue讨论这个问题。[/highlight]

2.在docker容器中运行Oracle数据库


docker run --name \
-p :1521 -p :5500 \
-e ORACLE_SID= \
-e ORACLE_PDB= \
-e ORACLE_CHARACTERSET= \
-v [:]/opt/oracle/oradata \
oracle/database:12.1.0.2-ee

Parameters:
–name: The name of the container (default: auto generated)
-p: The port mapping of the host port to the container port.
Two ports are exposed: 1521 (Oracle Listener), 5500 (OEM Express)
-e ORACLE_SID: The Oracle Database SID that should be used (default: ORCLCDB)
-e ORACLE_PDB: The Oracle Database PDB name that should be used (default: ORCLPDB1)
-e ORACLE_CHARACTERSET:
The character set to use when creating the database (default: AL32UTF8)
-v The data volume to use for the database.
Has to be owned by the Unix user “oracle” or set appropriately.
If omitted the database will not be persisted over container recreation.

[heading]1.问题描述[/heading]

Docker安装后默认的Storage Driver是AUFS,把存储驱动改成overlay2后,系统重启发现Docker daemon无法启动,查看状态提示是docker目录存在多个有效驱动,要求指定存储驱动。[highlight dark=”no”]Error starting daemon: error initializing graphdriver: /data/docker contains several valid graphdrivers: aufs, overlay; Please cleanup or explicitly…[/highlight]

尝试删除Docker目录的aufs目录,结果提示[highlight dark=”no”]rm: cannot remove ‘aufs’: Device or resource busy[/highlight]

[heading]2.原因[/heading]

查找挂载目录,发现 cat /proc/mounts | grep "docker",发现原来是aufs目录被挂载。

[heading]3.解决方法[/heading]
卸载该目录,[highlight dark=”no”] umount /var/lib/docker/aufs[/highlight],问题解决。

懒癌发作,直到春节假期才下定决心把公司的基础架构都迁移到Docker上,随之而来的是一大堆应用重新部署及系统重构的工作。公司大量的应用是基于Oracle数据库构建,所以安装Oracle Database变成了首要任务。虽然安装配置数据库是小菜一碟,但是习惯了登录OTN网站下载安装文件然后照步骤安装,在Linux环境下碰到的第一个问题是在Console的环境下没有浏览器,而下载Oracle 数据库安装文件需要登录OTN网站并同意Oracle的License协议方能下载。

虽然可能利用cookies export这些工具来实现,但是习惯了使用最简单的方法解决问题,直接利用Firefox浏览器可以达到这个目的。在工作计算机上用Firefox登录OTN网站,同意协议后点击下载你所需的数据库安装文件,当下载开始后点击暂停下载,然后在下载任务上右键,选择复制下载链接。

然后登录到Linux终端,用Wget加上复制的链接就可以实现在Linux终端下载OTN文件。

[heading]前言[/heading]
一直念叨着要把家里的无线路由改成能自动科学上网,但是平时在各种设备上习惯了用SS,懒癌晚期患者说了N长时间都没有动静。直至前几天,小朋友抱怨因为不能访问Google,查资料时搜索引擎都只能用度娘。关乎到下一代成长总得引起足够重视,但是哥穷得实在舍不得花钱买一个新的路由器,想起家里有个已经吃尘差不多两年的Model B树莓派,翻箱倒柜找出来,开始折腾。

以为无非是手到擒来的小case,把树莓派接上电来开始放狗搜,结果还要赔了差不多一个晚上才把它折腾完。原因主要有两个,一是网上大多数使用的无线网卡都是nl80211的,而俺手里只有型号为磊科Netcore NW337的Realtek 8192cu USB无线网卡,而默认的驱动程序并不支持hostapd;二是现在大家用的都是新版本的Raspbian操作系统,而俺是使用吃灰的旧派来折腾。所以此博文并没有多大的技术含量,无非是记录俺安装过程的备忘录,还有就是各种资料拼凑的整合。在此先感谢本文引用的各位大拿的资料。

[heading]硬件与系统[/heading]
系统是Raspbian Wheezy,更新了源后升级到了最新版本固件(sudo rpi-update)。
我利用树莓派的有线网卡连接电信的光猫,USB无线网卡做为网络信号发射器。USB无线网卡使用的是在某东买的磊科Netcore NW337网卡,成本低廉耐操是王道。再重点说明一下,这个网卡的芯片是Realtek 8192cu。利用以下命令可以确认无线网卡的芯片型号。
[highlight dark="no"]$ dmesg | grep 8192cu
[ 7.434462] usbcore: registered new interface driver rtl8192cu[/highlight]

[heading]基本设置[/heading]

1.树莓派基础设置

运行Raspbian系统配置命令,把文件系统扩展到整个SD卡,修改密码等。
[highlight dark="no"]$ sudo raspi-config[/highlight]

2.修改系统源
默认的源更新时速度会很慢,备份源文件,修改源至中国科学技术大学 Linux 用户协会的镜像。然后更新源,更新系统固件。
[highlight dark="no"]$ sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak
$ sudo echo "deb deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ wheezy main contrib non-free rpi" > /etc/apt/sources.list
$ sudo apt-get update
$ sudo rpi-update
[/highlight]

3.把eth0的IP设置为固定IP

原来系统的IP是DHCP,把IP地址改为固定,并把默认网关指定为电信光猫的IP。

[highlight dark="no"]$ sudo nano /etc/network/interfaces[/highlight]

把配置信息修改如下:

[highlight dark="no"]auto eth0
iface eth0 inet static
address 192.168.1.2
netmask 255.255.255.0
gateway 192.168.1.1
[/highlight]

192.168.1.1为电信光猫地址。

4.安装dnsmasq,设置DHCP服务

使用dnsmasq来做DHCP服务器,修改配置文件,设置DHCP的客户端IP网段。

[highlight dark="no"]$ sudo apt-get install dnsmasq

$ sudo nano /etc/dnsmasq.conf[/highlight]

对应修改以下几段内容。

[highlight dark="no"]#配置监听地址
listen-address=127.0.0.1,192.168.1.2,192.168.0.1
#配置DHCP分配段
dhcp-range=192.168.0.100,192.168.0.150,12h [/highlight]

注意192.168.0网段是无线路由分配给客户端的地址段。

重启dnsmasq服务以使更改生效。

[highlight dark="no"]$ sudo service dnsmasq restart[/highlight]

5.开启系统的包转发
Linux系统默认关闭了IP包转发,需要把包转发打开方能使用路由功能。
[highlight dark="no"]$ sudo nano /etc/sysctl.conf[/highlight]

去掉[highlight dark=”no”]net.ipv4.ip_forward=1[/highlight]前的注释,运行以下命令使其生效。同时启用eth0的NAT。

[highlight dark="no"]$ sudo sysctl -p
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE [/highlight]

[heading]Realtek 8192cu网卡驱动的安装[/heading]

正如前文所说,系统默认的Realtek 8192cu网卡驱动并不支持hostapd,所以必须重新编译网卡的驱动。

1.安装内核源

为了编译网卡驱动,你需要系统的内核源,下载Raspbian的内核源至当前用户的honme目录备用。

[highlight dark="no"]$ cd ~
$ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update
[/highlight]

下载后运行以下命令。

[highlight dark="no"]$ rpi-source[/highlight]

运行时很有可能会提示gcc版本错误,因为内核源所用的gcc版本要比当前树莓派安装的gcc版本要高。用以下命令查看对应的gcc版本并安装新版本。

[highlight dark="no"]$ cat /proc/version
$ gcc --version | grep gcc
$ sudo apt-get update
$ sudo apt-get install -y gcc-4.8 g++-4.8[/highlight]

然后设置gcc版本。

[highlight dark="no"]$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50[/highlight]

再一次运行命令安装内核源。

[highlight dark="no"]$ rpi-source[/highlight]

创建内核源目录的符号链接,此步非常重要,不做的话下面的命令会报错。

[highlight dark="no"]$ ln -s ~/linux/arch/arm ~/linux/arch/armv6l[/highlight]

2.重新编译rt8192c网卡驱动程序

系统默认的rt8192c驱动程序不支持AP模式,但是感谢dz0ny提供的代码,让这成为可能。从git克隆代码到本地。

[highlight dark="no"]$ cd ~
$ git clone https://github.com/dz0ny/rt8192cu.git[/highlight]

如果提示没有git请自行安装git。

构建驱动程序并安装。

[highlight dark="no"]$ cd ~/rt8192cu
$ sudo make
$ sudo make install[/highlight]

安装成功后程序会自动把旧的驱动程序放到黑名单里,运行以下命令确认。

[highlight dark="no"]$ cd ~/rt8192cu
$ cat /etc/modprobe.d/blacklist.conf
blacklist rtl8192cu[/highlight]

3.下载hostapd源并编译

网上的资料讲需要到Realtek官网下载hostapd压缩包并解决对应树莓派所需的hostapd源,估计是太旧的原因,现在Realtek官网已没有该文件下载。开始觉得应该在官方源安装个hostapd也可以,于是apt-get install hostapd,折腾了老半天,发现没法启动hostapd,最后还是卸载了,放狗搜到了RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911.zip,老老实实的做下来才能正常工作。

上传zip文件到用户目录下,解压。

[highlight dark="no"]$ unzip RTL8192xC_USB_linux_*.zip
[/highlight]

再解决你所需要的hostapd程序。

[highlight dark="no"]$ tar zxvf RTL8188C_8192C_USB_linux_*/wpa_supplicant_hostapd/wpa_supplicant_hostapd-0.8_rtw_*.tar.gz[/highlight]

切换到hostapd源,修改Makefile。

[highlight dark="no"]$ cd ~/wpa_supplicant_hostapd-0.8_*/hostapd/
$ sudo nano Makefile
[/highlight]

找到CFLAGS节内容修改为:

[highlight dark="no"]CFLAGS=-MMD -Os
[/highlight]

编译hostapd,并把可执行文件复制至正确位置。

[highlight dark="no"]$ sudo make
$ sudo cp hostapd hostapd_cli /usr/local/sbin/
[/highlight]

4.配置hostapd

创建hostapd配置文件名录,编辑配置文件。

[highlight dark="no"]$ sudo mkdir /etc/hostapd
$ sudo nano /etc/hostapd/hostapd.conf
[/highlight]

我的hotapd.conf文件长这个样子。

[highlight dark="no"]ctrl_interface=/var/run/hostapd
###############################
# Basic Config
###############################
macaddr_acl=0 auth_algs=1
driver=rtl871xdrv
##########################
# Local configuration...
##########################
interface=wlan0
hw_mode=g
ieee80211n=1
wme_enabled=1
channel=13
ssid=Tongfu
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_psk=IL0veT0ngfu
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
[/highlight]

运行命令来验证hostapd配置文件,没有错误提示CTRL+C结束,修改/etc/default/hostapd文件,编辑/etc/default/hostapd,改变DAEMON_CONF的配置为[highlight dark=”no”]DAEMON_CONF=”/etc/hostapd/hostapd.conf”[/highlight] 。

[highlight dark="no"]$ sudo hostpad -d /etc/hostapd/hostapd.conf
$ sudo nano /etc/default/hostapd
[/highlight]

创建初始化脚本到/etc/init.d中,以便设置开机启动AP服务。

[highlight dark="no"]$ sudo nano /etc/init.d/hostapd
[/highlight]

文件代码如下:

[highlight dark="no"]#!/bin/bash
# /etc/init.d/hostapd

### BEGIN INIT INFO
# Provides: hostapd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Managing hostapd
# Description: This service is used to manage hostapd (WiFi Access Point)
### END INIT INFO

case "$1" in
start)
echo
echo "Starting hostapd..."
echo
if [ ! -d /var/run/hostapd ]; then
rm -rf /var/run/hostapd
mkdir /var/run/hostapd
fi

/usr/local/sbin/hostapd -B -P /var/run/hostapd/wlan0.pid /etc/hostapd/hostapd.conf
;;
stop)
echo
echo "Stopping hostapd..."
echo
if [ -e /var/run/hostapd/wlan0.pid ]; then
read pid < /var/run/hostapd/wlan0.pid if [ x$pid != x ]; then kill $pid fi fi ;; restart) echo echo "Restarting hostapd..." echo if [ -e /var/run/hostapd/wlan0.pid ]; then read pid < /var/run/hostapd/wlan0.pid if [ x$pid != x ]; then kill $pid fi fi if [ ! -d /var/run/hostapd ]; then rm -rf /var/run/hostapd mkdir /var/run/hostapd fi /usr/local/sbin/hostapd -B -P /var/run/hostapd/wlan0.pid /etc/hostapd/hostapd.conf ;; *) echo echo "Usage: /etc/init.d/hostapd start|stop|restart" echo exit 1 ;; esac exit 0 [/highlight]

赋予文件可执行,并且开机启动。

[highlight dark="no"]$ sudo chmod +x /etc/init.d/hostapd
$ sudo update-rc.d hostapd defaults
[/highlight]

现在启动hostapd服务,应该可以用电脑搜到热点并连接了。

[highlight dark="no"]$ sudo service hostapd start
[/highlight]

至此,利用Realtek 8192cu USB无线网卡在树莓派建立无线路由器的工作已完成,你可以通过无线网络连接路由,正常的上网浏览了。但是要透明的访问Google,还是得进行科学上网的设置。

[heading]科学上网配置[/heading]

1.建立无污染DNS
使用中科大的DNS,修改/etc/dnsmasq.conf。
[highlight dark="no"]$ sudo nano /etc/dnsmasq.conf
[/highlight]

在文件最后加入以下规则:

[highlight dark="no"]no-resolv
server=202.38.93.153
server=202.141.162.123
[/highlight]

重启dnsmasq。

[highlight dark="no"]$ sudo service dnsmasq restart
[/highlight]

2.安装shadowsocks

通过pip安装shadowsocks,建立配置文件

[highlight dark="no"]$ sudo pip install shadowsocks
$ sudo nano /etc/shadowsocks.conf
[/highlight]

配置文件内容如下:
[highlight dark="no"]
{
"server":"xxx.xxx.xxx.xxx",
"server_port":9999,
"local_port":1088,
"password":"xxxxx",
"timeout":300,
"method":"aes-256-cfb",
"fast_open": false,
"workers": 1
}
[/highlight]

保存文件后启动ss服务。

[highlight dark="no"]$ sudo sslocal -c /etc/shadowsocks.conf -d start
[/highlight]

如果没有问题把命令加入/etc/rc.local来实现开机自启动。

3.安装redsocks

安装redsocks并编辑配置文件。

[highlight dark="no"]$ sudo apt-get install redsocks
$ sudo nano /etc/redsocks.conf
[/highlight]

修改配置文件的redsocks部分。

[highlight dark="no"]
redsocks {
local_ip = 0.0.0.0;
local_port = 12345;
ip = 127.0.0.1;
port = 1088;
}
[/highlight]

启动redsocks,确认ss和redsocks都启动

[highlight dark="no"]$ sudo service redsocks start
$ netstat -an|grep 1088
$ netstat -an|grep 12345
[/highlight]

4.安装ipset并导入chnroute

科学上网的规则:凡是国外的网站都用shadowsocks加速。因此,我们借助于ipset保存国内ip段。

安装ipset,导出国内ip地址段,再导入到ipset

[highlight dark="no"]$ sudo apt-get install ipset
$ curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > chnroute.txt
$ sudo ipset create chnroute hash:net
$ cat chnroute.txt | sudo xargs -I ip ipset add chnroute ip
[/highlight]

5.备份ipset并开机载入

导入ipset的过程非常缓慢,不适合每次开机都执行。我们可以将ipset的结果保存,每次开机导入。

[highlight dark="no"]$ sudo ipset save chnroute > /etc/chnroute.ipset
[/highlight]

然后在/etc/rc.local中加入如下语句,实现开机启动。

[highlight dark="no"]
ipset restore < /etc/chnroute.ipset [/highlight]

6.导入防火墙规则

[highlight dark="no"]sudo iptables -t nat -N SHADOWSOCKS

sudo iptables -t nat -A SHADOWSOCKS -d $server_IP -j RETURN

sudo iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -m set --match-set chnroute dst -j RETURN

sudo iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 12345

sudo iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS
sudo iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS
[/highlight]

其中$server_IP是你的VPS的地址,保存规则后确认可以正常翻墙。可把规则加载写入到/etc/rc.local中,实现开机重新生效防火墙规则。

在客户端连接此无线路由,开始自由自在的上网吧。

[heading]引用与感谢[/heading]

没有网上前人大量的实验和分享的文章,俺绝对是没办法自己搞定树莓派无线路由的设置的,特别感谢以下博客文章。

1.来自Wannabe Nerd RandomnessWiFi access point using a Realtek 8192cu based USB WiFi dongle with a Raspberry Pi,本文关于Realtek 8192cu网卡的设置引用均来自此文章,thanks Jack Flushell for your great sharing.

2.本文科学上网设置部分引用于Tony Lee的博客文章用树莓派打造无线中继科学上网路由器,感谢Tony的分享,同在魔都,有缘的话自当结识。

[heading]问题描述[/heading]

Oracle WebCenter Portal 12C创建新Portal时,走完创建向导,门户创建完成,然后报错。

[highlight dark=”no”]Create Portal

Portal creation completed with errors.
createSpaceError[/highlight]

[heading]解决过程[/heading]

这算是最近折腾WCP比较坑的一个问题,花费了大量的时间与精力解决这个问题。开始时在Oracle Support找答案,发现在WCP 12C早期版本是有这样一个不能创建Portal的bugs,于是下载了所有能找到的系统补丁,用Opatch一一打上去,但是不能创建Portal的问题依旧;

只能回到原点,仔细去看Portal Server的Log。因为我们的门户是自己写的Portal Extension,看见有些Bean有报错,于是把矛头对准了自己的工程代码,好不容易把代码调得完全没有报错,发布到系统上无法创建Portal(在这里不得不吐槽一把O记,11g的Portal Framework方式没有了,现在改写portal只能用extension方式,程序的调试那可叫一个费时间,哥们有一半的工作时间是浪费在等待中)。

看来也不是代码的问题,又乖乖的回去一行行的看Log。还是最后无意在想到,在公司的环境里用Weblogic内置的ldap是没这个问题的,而客户的环境是配置了外部的LDAP做用户身份验证就不能创建门户了,看来问题的症结还是用户权限设置。重新配置了门户的权限设置,最后终于能成功创建门户了。

一大早接到同学的求救电话,说升级社保管理系统时,系统报“[highlight dark=”no”]进程性能计数器已禁用[/highlight]”的错误,没法升级。

388689530456590452

心里想着无非是小事一桩,上网搜了搜解决方法,无非是两种方式,把性能进程计数器打开就好。

1.修改注册表,把[highlight dark=”no”]Disable Performance Counters[/highlight]键参数设置为0

[highlight dark=”no”]HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PerfProc\Performance[/highlight]

2.在命令行运行[highlight dark=”no”]lodctr /r[/highlight]

依葫芦画瓢把解决方法告诉同学,结果回复说系统重启后还是报错。只好自己远程登录到同学的电脑上,发现那兄弟还在用着Windows XP系统,自己又照着解决方法试了一遍,问题依旧。

看来是老革命碰上了新问题,为了保全哥在亲友圈中“电脑高手”的名声,只好打开一台XP虚机做试验了,经过一番折腾,总算把问题解决了。

原来同学的System32目录上,两个与性能计数器相关的文件,[highlight dark=”no”]perfc009.dat与perfh009.dat不知啥原因,分别被改名为perfd009.dat和perfi009.dat了[/highlight],把这两个文件名字改回去再运行升级程序,顺利完成。

懒得去探究为何文件会被改名了,不过想不明白的是社保系统的升级为毛需要去取性能进程计数器呢?

新部署的WebCenter Portal服务器,写了Portal Extension后发布到服务器,门户不能正常运行。找到问题修正后门户能访问,但是发现WebCenter Portal不断抛出一个[highlight dark=”no”]java.lang.IllegalArgumentException: URI scheme is not “file”[/highlight]的错误,并记录到日志文件。

[heading]问题描述[/heading]

WebCenter Portal不断在日志生成级别为[Warning]的URI scheme is not “file”错误,完整消息如下:

[2016-09-23T11:56:53.293+08:00] [WC_Portal] [WARNING] [] [org.eclipse.persistence.jaxb.BeanValidationHelper] [tid: [ACTIVE].ExecuteThread: ’21’ for queue: ‘weblogic.kernel.Default (self-tuning)’] [userId: weblogic] [ecid: 74e955f6-ec4b-4aa5-8713-c12464770bc1-000002c8,0] [APP: webcenter] [partition-name: DOMAIN] [tenant-name: GLOBAL] [DSID: 0000LTL6BfOFw000jzwkno1Nt9jz000003] Error parsing validation.xml the async way[[
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: URI scheme is not “file”
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at org.eclipse.persistence.jaxb.BeanValidationHelper.getConstraintsMap(BeanValidationHelper.java:139)
at org.eclipse.persistence.jaxb.BeanValidationHelper.isConstrained(BeanValidationHelper.java:120)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.isConstrainedObject(JAXBBeanValidator.java:255)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.shouldValidate(JAXBBeanValidator.java:206)
at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:587)
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:481)
at org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.writeTo(AbstractRootElementJaxbProvider.java:201)
at org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.writeTo(AbstractRootElementJaxbProvider.java:180)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at weblogic.jaxrs.server.internal.ChunkedOutputWriter.aroundWriteTo(ChunkedOutputWriter.java:65)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1130)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:683)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:424)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:414)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:312)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:292)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:460)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:286)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:260)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:137)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:350)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:25)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.webcenter.content.integration.servlets.ContentServletFilter.doFilter(ContentServletFilter.java:168)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.webcenter.jaxrs.services.portal.controller.swagger.SwaggerApiOriginFilter.doFilter(SwaggerApiOriginFilter.java:44)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.adf.share.http.ServletADFFilter.doFilter(ServletADFFilter.java:77)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.webcenter.portal.context.impl.PortalRequestServletFilter$1.call(PortalRequestServletFilter.java:53)
at oracle.webcenter.portal.context.impl.PortalRequestServletFilter$1.call(PortalRequestServletFilter.java:48)
at oracle.webcenter.portal.context.impl.PortalRequestExecutorImpl.execute(PortalRequestExecutorImpl.java:47)
at oracle.webcenter.portal.context.impl.PortalRequestServletFilter.doFilter(PortalRequestServletFilter.java:47)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:141)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:649)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:124)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:232)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:94)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:141)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:649)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:124)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:232)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:94)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.dms.servlet.DMSServletFilter.doFilter(DMSServletFilter.java:224)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at oracle.security.jps.ee.http.JpsAbsFilter$1.run(JpsAbsFilter.java:141)
at java.security.AccessController.doPrivileged(Native Method)
at oracle.security.jps.util.JpsSubject.doAsPrivileged(JpsSubject.java:315)
at oracle.security.jps.ee.util.JpsPlatformUtil.runJaasMode(JpsPlatformUtil.java:649)
at oracle.security.jps.ee.http.JpsAbsFilter.runJaasMode(JpsAbsFilter.java:124)
at oracle.security.jps.ee.http.JpsAbsFilter.doFilter(JpsAbsFilter.java:232)
at oracle.security.jps.ee.http.JpsFilter.doFilter(JpsFilter.java:94)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:32)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:78)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3654)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3620)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:326)
at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:196)
at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.java:2423)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2280)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2258)
at weblogic.servlet.internal.ServletRequestImpl.runInternal(ServletRequestImpl.java:1626)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1586)
at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.java:270)
at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:348)
at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:333)
at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:54)
at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:617)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:397)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:346)
Caused by: java.lang.IllegalArgumentException: URI scheme is not “file”
at java.io.File.<init>(File.java:421)
at org.eclipse.persistence.jaxb.ValidationXMLReader.parseValidationXML(ValidationXMLReader.java:147)
at org.eclipse.persistence.jaxb.ValidationXMLReader.call(ValidationXMLReader.java:67)
at org.eclipse.persistence.jaxb.ValidationXMLReader.call(ValidationXMLReader.java:1)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

[heading]原因[/heading]

一开始以为是自己代码的问题,从头到尾Debug了N遍找问题,但是一发布到WebCenter Portal,问题依旧。这令人不得不怀疑是WebCenter Portal的问题了。Google了一把,发现原来是产品的一个bug,据说O记会在下一个版本修复。

[heading]解决方法[/heading]

虽说这个问题不影响使用,但是做为非典型的强迫症患者,看着这样的消息连写代码都受影响。不能完全解决只能把这个报错信息关掉了。

打开WebCenter Portal所在的服务器EM,找到Portal服务器,选择Log Configuration,在Log Level选项卡下找BeanValidationHelper,把Logging Level从[highlight dark=”no”]WARNING[/highlight]改为[highlight dark=”no”]SEVERE[/highlight],保存更改,这下终于天下太平了。

loglevel

坑爹的O记。

当想把WebCenter Space扩展程序发布至WebCenter Portal 12c时出现这个错误。

[highlight dark=”no”][Deployer:149140]The task cannot be processed further until the current edit session is activated.[/highlight]

 

space-error

 

[heading]原因[/heading]

The user is the current owner of the domain configuration edit lock.

[heading]解决方法[/heading]

Activate (or cancel) the edit session. The user can exit the deployer tool without affecting the task.

说成人话就是重启管理服务器或者在开发机器上把Default Domain删除了再重建即可解决。

 

[heading]1. Oracle JET是什么鬼[/heading]

按官方的说法,Oracle JET是给JavaScript开发者提供云端数据可视化的工具。JET使用了很多第三方的JavaScript库,例如jQuery,jQueryUI,Knockout,RequireJS和Hammer(如果在本地运行,需要Node.js支持)。

按俺的理解,JET就是O记把一堆前端工具整合到一起的大杂汇,让对前端框架不是特别熟的程序猿媛们能有一个快速开发响应式前端页面的路子。JET可以用于WEB页面开发,也可用于APP的开发。

JET的架构是这样的(基于MVVM设计模式)

Architecture

从官方的示例程序来看,JET做出来的页面效果还是不错的。

Workbetter

[heading]2. 对Oracle JET的看法[/heading]

其实,开始的时候俺对Oracle JET的态度本来是抗拒的,认为没必要再重复造一个轮子。

wechatjet

个人对于知乎上这个问题的回答深以为然。

zhihujet

不过最近没有啥新东西玩,加上想在一些项目上看看能否把JET引进来(毕竟还是有些基于O记产品的项目), 于是报了官网上一个在线的JET Training,对着官方的文档安装环境。

 

[heading]3. 在Windows系统上安装JET[/heading]

Oracle官网上的步骤已经很详细,基本上照着示例步骤安装即可完成。JET提供两种安装方式(或者称之为JET应用生成方式),一种是前端狗熟悉的Yeoman生成方式,一是使用Netbeans IDE引入JET包的方式(在这时深深鄙视O记一把,居然不把自家JDeveloper的支持做出来,使得如果要用JET与ADF应用结合的话必须使用两个IDE进行开发)。

[accordion title=”3.1 以Yeoman方式安装” is_open=”yes”]

1).首先安装Git

下载Git Windows客户端,按提示完成安装。

2). 安装Node.js

前面提过,要在本地上运行JET必须Node.js支持,下载Windows下包含npm的Node.js安装包

downloadnode

进行Node.js的安装。

installnode1

 

installnode2

 

installnode3

稳定版的Node.js带的npm版本过低,我们需要升级npm,运行命令npm install –g npm进行升级。完成后用npm -v确认npm版本。

npmver

3). 安装Yeoman, Grunt, Bower工具包

运行命令npm –g install o bower grunt-cli,安装所需的工具包。

npmtool1

npmtool2

4). 安装JET Yeoman生成器

运行命令npm -g install generator-oraclejet

jetgenerator

5).基于模板生成第一个JET Web应用

运行命令yo oraclejet firstjet  –template=basic生成第一个JET Web应用。

firstjet1

firstjet2

应用生成成功后,用grunt生成并启动应用。

grunt build

grunt serve

firstjet3

访问本地服务地址,可以看到第一个JET应用的界面。

firstjet4

[/accordion]

[accordion title=”3.2 用Netbeans进行JET应用开发” is_open=”no”]

1).安装Netbeans

Netbeans站点下载合适的安装包,进行Netbeans安装。

downloadnetbeans

netbeans1

 

2).下载Oracle JET压缩包

OTN下载JET压缩包oraclejet.zip并保存。

jetdownload

3)在Netbean创建Oracle JET应用

打开Netbean,新建一个HTML5/JavaScript应用程序。

newproject1

下一步选择项目位置。

newproject2

下一步,选择之前下载的OracleJET压缩包为模板来源,点下一步。选择你所需的工作,点完成,完成OracleJET应用的创建。

newproject4

[/accordion]

[message type=”attention”]温馨提示:如果你在天朝,安装支持包时,请注意科学上网[/message]