diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
index 523b9ae543..eaea440e3a 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java
@@ -1023,22 +1023,30 @@ public byte[] getBytes(ResultSet rs, int column)
return (byte[]) rs.getObject(column);
}
- int type = rs.getMetaData().getColumnType(column);
- switch (type) {
- case Types.BLOB:
- Blob blob = getBlob(rs, column);
- if (blob == null) {
- return null;
- }
-
- int length = (int) blob.length();
- if (length == 0) {
- return null;
- }
- return blob.getBytes(1, length);
- case Types.BINARY:
- default:
+ // At this point we don't have any idea if the DB2 column was defined as
+ // a blob or if it was defined as CHAR for BIT DATA.
+ // First try as a blob, if that doesn't work, then try as CHAR for BIT DATA
+ // If that doesn't work, then go ahead and throw the first exception
+ try {
+ Blob blob = getBlob(rs, column);
+ if (blob == null) {
+ return null;
+ }
+
+ int length = (int) blob.length();
+ if (length == 0) {
+ return null;
+ }
+
+ return blob.getBytes(1, length);
+ }
+ catch (SQLException e) {
+ try {
return rs.getBytes(column);
+ }
+ catch (SQLException e2) {
+ throw e;
+ }
}
}
diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java
index 16e3027798..6b06ad7656 100644
--- a/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java
+++ b/openjpa-kernel/src/main/java/org/apache/openjpa/meta/AbstractCFMetaDataFactory.java
@@ -53,6 +53,7 @@
import org.apache.openjpa.lib.meta.MetaDataIterator;
import org.apache.openjpa.lib.meta.MetaDataParser;
import org.apache.openjpa.lib.meta.MetaDataSerializer;
+import org.apache.openjpa.lib.meta.OSGiBundleMetaDataIterator;
import org.apache.openjpa.lib.meta.ResourceMetaDataIterator;
import org.apache.openjpa.lib.meta.URLMetaDataIterator;
import org.apache.openjpa.lib.meta.ZipFileMetaDataIterator;
@@ -759,6 +760,15 @@ public File run() {
} catch (PrivilegedActionException pae) {
throw (IOException) pae.getException();
}
+ } else if ("bundle".equals(url.getProtocol())) {
+
+ if (log.isTraceEnabled()) {
+ log.trace(_loc.get("scanning-osgi-bundle", url));
+ }
+
+ MetaDataIterator mdi = new OSGiBundleMetaDataIterator(url, newMetaDataFilter());
+ scan(mdi, cparser, names, true, url);
+
} else {
// Open an InputStream from the URL and sniff for a zip header. If it is, then this is
// a URL with a jar-formated InputStream, as per the JPA specification. Otherwise, fall back
diff --git a/openjpa-lib/pom.xml b/openjpa-lib/pom.xml
index c828e61666..2ad9fe00b5 100644
--- a/openjpa-lib/pom.xml
+++ b/openjpa-lib/pom.xml
@@ -78,7 +78,13 @@
org.apache.geronimo.specs
geronimo-validation_1.0_spec
provided
-
+
+
+ org.osgi
+ org.osgi.core
+ 4.2.0
+ provided
+
diff --git a/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/OSGiBundleMetaDataIterator.java b/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/OSGiBundleMetaDataIterator.java
new file mode 100644
index 0000000000..7f86ffbe40
--- /dev/null
+++ b/openjpa-lib/src/main/java/org/apache/openjpa/lib/meta/OSGiBundleMetaDataIterator.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openjpa.lib.meta;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+import java.io.*;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * Created by andrei on 24.07.2014.
+ */
+public class OSGiBundleMetaDataIterator implements MetaDataIterator, MetaDataFilter.Resource {
+
+ private InputStream stream;
+ private Bundle bundle;
+ private Enumeration entries;
+ private MetaDataFilter filter;
+ private URL entry;
+ private URL last;
+ private byte[] buf;
+
+ public OSGiBundleMetaDataIterator(URL bundleUrl, MetaDataFilter filter) {
+
+ BundleContext ctx = FrameworkUtil.getBundle(OSGiBundleMetaDataIterator.class).getBundleContext();
+ long bundleId = Long.parseLong(bundleUrl.getHost().substring(0, bundleUrl.getHost().indexOf(".")));
+ this.bundle = ctx.getBundle(bundleId);
+ entries = this.bundle.findEntries("/", "*.class", true);
+ this.filter = filter;
+
+ }
+
+ @Override
+ public boolean hasNext() throws IOException {
+
+ if (entries == null) {
+ return false;
+ }
+
+ if (entry != null) {
+ return true;
+ }
+
+ last = null;
+ buf = null;
+
+ if (!entries.hasMoreElements()) {
+ return false;
+ }
+
+ URL tmp;
+ while ( entry == null && (entries.hasMoreElements() && (tmp = this.entries.nextElement()) != null)) {
+ entry = tmp;
+ stream = entry.openStream();
+ if (filter != null && !this.filter.matches(this)) {
+ entry = null;
+ }
+
+ }
+
+ return entry != null;
+
+ }
+
+ @Override
+ public Object next() throws IOException {
+
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+
+ String name = entry.toString();
+ last = entry;
+ entry = null;
+
+ return name;
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ if (last == null)
+ throw new IllegalStateException();
+
+ return last.openStream();
+ }
+
+ @Override
+ public File getFile() throws IOException {
+ return null;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public String getName() {
+ return entry.toString();
+ }
+
+ @Override
+ public byte[] getContent() throws IOException {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ byte[] buf = new byte[1024];
+ for (int r; (r = stream.read(buf)) != -1; bout.write(buf, 0, r)) ;
+ buf = bout.toByteArray();
+ stream.close();
+ return buf;
+ }
+}