Datanucleus + OSGi (Equinox) gives error No suitable driver found for jdbc:mysql://localhost:3306/jdoosgitest - rdbms

I am trying to use datanucleus jdo implementation inside the osgi environment but I am constantly getting error : No suitable driver found for jdbc:mysql://localhost:3306/jdoosgitest
I have been following the link
http://www.datanucleus.org/servlet/wiki/display/USERS/HOWTO+Use+Datanucleus+with+OSGi+and+Spring+DM
But I don't want to use SpringDM. Firstly because I don't know Spring and I am new to OSGi and JDO also.
Environment Details
DataNucleus Bundles and changes in MANIFEST.MF
datanucleus-api-jdo-3.0.0-m2.jar -- Eclipse-BuddyPolicy=registered
datanucleus-core-3.0.0-m2.jar -- Eclipse-BuddyPolicy=registered
datanucleus-rdbms-3.0.0-m2.jar -- Eclipse-BuddyPolicy=registered
jdo-api-3.0.jar -- Eclipse-BuddyPolicy=registered
Eclipse Bundle And Equinox
org.eclipse.core.contenttype_3.4.1.R35x_v20090826-0451.jar
org.eclipse.core.jobs_3.4.100.v20090429-1800.jar
org.eclipse.core.runtime_3.5.0.v20090525.jar
org.eclipse.equinox.app_1.2.1.R35x_v20091203.jar
org.eclipse.equinox.common_3.5.1.R35x_v20090807-1100.jar
org.eclipse.equinox.preferences_3.2.301.R35x_v20091117.jar
org.eclipse.equinox.registry_3.4.100.v20090520-1800.jar
org.eclipse.osgi_3.5.2.R35x_v20100126.jar
org.eclipse.osgi.services_3.2.0.v20090520-1800.jar
MyBundle:
TestJdoOSGi
Other lib used
TestJdoOSGi/lib/mysql-connector-java-5.1.14-bin.jar
TestJdoOSGi/META-INF/MANIFEST.MF --
Eclipse-RegisterBuddy= org.datanucleus.store.rdbms, javax.jdo, org.datanucleus.api.jdo, org.datanucleus
Bundle-ClassPath= bin, lib/mysql-connector-java-5.1.14-bin.jar
The method that gets the PersistenceManager Factory
public PersistenceManagerFactory createPMF()
{
Map defaultProps = new HashMap();
defaultProps.put("javax.jdo.PersistenceManagerFactoryClass", "org.datanucleus.api.jdo.JDOPersistenceManagerFactory");
defaultProps.put("datanucleus.metadata.validate", "false");
defaultProps.put("javax.jdo.option.ConnectionDriverName", "org.gjt.mm.mysql.Driver");
defaultProps.put("javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/jdoosgitest");
defaultProps.put("javax.jdo.option.ConnectionUserName", "root");
defaultProps.put("javax.jdo.option.ConnectionPassword", "root");
defaultProps.put("javax.jdo.option.Mapping", "mysql");
defaultProps.put("datanucleus.autoCreateSchema", "true");
defaultProps.put("datanucleus.validateTables", "false");
defaultProps.put("datanucleus.validateConstraints", "false");
ClassLoader dirverClassLoader = null;
try {
dirverClassLoader = Activator.bundleContext.getBundle().loadClass("test.jdo.osgi.MyTest").getClassLoader();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
defaultProps.put("datanucleus.primaryClassLoader", dirverClassLoader);
ClassLoader factoryClassLoader = getFactoryClassLoader();
PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory(defaultProps, factoryClassLoader);
return pmf;
}
private ClassLoader getFactoryClassLoader() {
ClassLoader classloader = null;
Bundle[] bundles = Activator.bundleContext.getBundles();
for (int x = 0; x < bundles.length; x++) {
if ("org.datanucleus.api.jdo".equals(bundles[x].getSymbolicName())) {
try {
classloader = bundles[x].loadClass("org.datanucleus.api.jdo.JDOPersistenceManagerFactory").getClassLoader();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
return classloader;
}

Related

How do I populate mongo repositories automatically?

Using Spring Data MongoDB with MongoRepository. I have this bean
#Bean
public Jackson2RepositoryPopulatorFactoryBean repositoryPopulator() {
Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();
try {
factory.setResources(resourceResolver.getResources("classpath:static/collections/*.json"));
} catch (IOException e) {
log.error("Could not load data", e);
}
return factory;
}
which just works fine with fongo (db is dropped at the end of a test run) but not with real mongo. If I leave the bean as it is and I switch to real mongo instance, then I get my data base populated but only the first run, if I re-run the project (+tests) then it fails because it's already populated (getting DuplicateKeyException).
How do I populate only on the case the repositories are empty?
Consider using data migration tools like Mongobee. This is basically Liquibase/Flyway for MongoDB.
#Bean
public Jackson2RepositoryPopulatorFactoryBean repositoryPopulator() throws Exception {
Jackson2RepositoryPopulatorFactoryBean factory = new Jackson2RepositoryPopulatorFactoryBean();
try {
Resource[] resources = resourceResolver.getResources("classpath:static/collections/*.json");
//resources to list so I can add only the necessary resources
List<Resource> resourcesToFill = new ArrayList<>();
for (Resource r : resources) {
String collection = r.getFilename().substring(0, r.getFilename().length() - 5);
if (!mongoTemplate().collectionExists(collection))
resourcesToFill.add(r);
}
//back to Array...
resources = new Resource[resourcesToFill.size()];
for(int i=0; i<resources.length; i++)
resources[i] = resourcesToFill.get(i);
factory.setResources(resources); // <-- the reason of this shitty code, why the hell use Array?
} catch (IOException e) {
log.error("Could not load data", e);
}
return factory;
}

Junit testing for database conection

Is there a way to test below code.Here I am connecting to database with JNDI.I am new to mockito and not getting a way to test the same.
#SuppressWarnings("unused")
public Connection getJNDIConnection() {
Connection result = null;
try {
InitialContext initialContext = new InitialContext();
if (initialContext == null) {
LOGGER.info("JNDI problem. Cannot get InitialContext.");
}
DataSource datasource = (DataSource) initialContext.lookup(jndiName);
if (datasource != null) {
result = datasource.getConnection();
} else {
LOGGER.info("Failed to lookup datasource.");
}
} catch (NamingException ex) {
LOGGER.error("Cannot get connection: " + ex);
} catch (SQLException ex) {
LOGGER.error("Cannot get connection: " + ex);
}
return result;
}
Of course, you can to do it, but I think you should read the documentation yourself. The main points here is:
InitialContext initialContext = mock(InitialContext.class);
DataSource dataSource = mock(DataSource.class);
Connection expected = mock(Connection.class);
whenNew(InitialContext.class).withNoArguments().thenReturn(initialContext);
when(initialContext.lookup(jndiName)).thenReturn(dataSource);
when(initialContext.getConnection()).thenReturn(connection);
Connection result = intatnceOfCalss.getJNDIConnection();
assertSame("Should be equals", expected, result);
Also you should use PowerMock to mock constructors and static methods. To have deal with Logger, just add this code:
#BeforeClass
public static void setUpClass() {
mockStatic(LoggerFactory.class);
Logger logger = mock(Logger.class);
when(LoggerFactory.getLogger(ApplySqlFileIfExistsChange.class)).thenReturn(logger);
}
Don't forget about annotations:
#RunWith(PowerMockRunner.class)
#PrepareForTest({LoggerFactory.class})
Try to read this doc http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html

Titan 0.5.1 Customize object in my node

I have a problem with Titan 0.5.1. I try to upgrade Titan 0.4.4 to 0.5.1. Currently, I use berkeleyje and i configure like this :
BaseConfiguration conf = new BaseConfiguration();
// Storage info
conf.setProperty("storage.directory", directory + File.separator + DB_NAME);
conf.setProperty("storage.backend", "berkeleyje");
// Class info storage
conf.setProperty("attributes.allow-all", "true");
conf.setProperty("attributes.custom.attribute1.attribute-class", "model.Property");
conf.setProperty("attributes.custom.attribute1.serializer-class", "PropertySerializer");
TitanGraph graph = TitanFactory.open(conf);
For serialize my object i use :
public class PropertySerializer implements AttributeSerializer<Property> {
#Override
public Property read(ScanBuffer buffer) {
Property object = null;
ArrayList<Byte> records = new ArrayList<Byte>();
try {
while (buffer.hasRemaining()) {
records.add(Byte.valueOf(buffer.getByte()));
}
Byte[] bytes = records.toArray(new Byte[records.size()]);
ByteArrayInputStream bis = new ByteArrayInputStream(ArrayUtils.toPrimitive(bytes));
ObjectInput in = new ObjectInputStream(bis);
object = (Property) in.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
#Override
public void write(WriteBuffer out, Property attribute) {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput outobj;
outobj = new ObjectOutputStream(bos);
outobj.writeObject(attribute);
byte[] propertybyte = bos.toByteArray();
for (int i = 0; i < propertybyte.length; i++) {
out.putByte(propertybyte[i]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void verifyAttribute(Property value) {
// TODO Auto-generated method stub
}
#Override
public Property convert(Object value) {
// TODO Auto-generated method stub
return null;
}
}
Typically, i add a property like this :
Vertex r = this.model.addVertex(null);
Property p = new Property();
r.setProperty("object", p);
this.model.commit();
But i obtain this error :
Exception in thread "main"
com.thinkaurelius.titan.core.TitanException: Could not commit
transaction due to exception during persistence at
com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx.commit(StandardTitanTx.java:1310)
at
com.thinkaurelius.titan.graphdb.blueprints.TitanBlueprintsGraph.commit(TitanBlueprintsGraph.java:60)
Caused by: com.thinkaurelius.titan.core.TitanException: Serializer
Restriction: Cannot serialize object of type: class
.model.Property at
com.thinkaurelius.titan.graphdb.database.serialize.StandardSerializer$StandardDataOutput.writeClassAndObject(StandardSerializer.java:160)
at
com.thinkaurelius.titan.graphdb.database.EdgeSerializer.writePropertyValue(EdgeSerializer.java:383)
at
com.thinkaurelius.titan.graphdb.database.EdgeSerializer.writePropertyValue(EdgeSerializer.java:377)
at
com.thinkaurelius.titan.graphdb.database.EdgeSerializer.writeRelation(EdgeSerializer.java:293)
at
com.thinkaurelius.titan.graphdb.database.StandardTitanGraph.prepareCommit(StandardTitanGraph.java:485)
at
com.thinkaurelius.titan.graphdb.database.StandardTitanGraph.commit(StandardTitanGraph.java:613)
at
com.thinkaurelius.titan.graphdb.transaction.StandardTitanTx.commit(StandardTitanTx.java:1299)
Can you help me please ? Because, with 0.4.4 version it worked. The new documentation don't help me.
Thanks in advance

Camel JPA - No Persistence provider for EntityManager named camel

I am trying to get the following code to work so I can consume from a JPA entity.
String DATASOURCE_CONTEXT = "java:jboss/datasources/WikiDS";
Connection result = null;
DataSource datasource = null;
try {
Context initialContext = new InitialContext();
datasource = (DataSource)initialContext.lookup(DATASOURCE_CONTEXT);
if (datasource == null) {
System.out.println("Data source is null");
}
else {
System.out.println("Data source is OK!!!");
}
}
catch(NamingException ex) {
System.out.println("Naming exception is: " + ex.getMessage());
}
SimpleRegistry reg = new SimpleRegistry() ;
reg.put("myDataSource",datasource);
CamelContext context = new DefaultCamelContext(reg);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false");
context.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
context.addRoutes(new RouteBuilder() {
public void configure() {
from("jpa://org.apache.camel.example.jmstofile?consumer.namedQuery=step1&consumeDelete=false").to("file://test");
}
});
ProducerTemplate template = context.createProducerTemplate();
context.start();
Whatever I do I get the following exception.
[ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.1.1:java (default-cli) on project camel-example-jms-file: An exception occured while executing the Java class. null: InvocationTargetException: No Persistence provider for EntityManager named camel.
Any ideas how to fix this?
Regards,
Sean
Add &persistenceUnit=<name-of-your-unit> to your URI, where <name-of-your-unit> is the name of the persistence unit given in persistence.xml.

Android Webview set proxy programmatically Kitkat

How can we set proxy in Android webview programmatically on latest Kitkat release?
This SO link WebView android proxy talks about version upto SDK version 18. But those solution no more works with Kitkat as underlying webkit implementation is changed and it uses chromium now.
Here is my solution:
public static void setKitKatWebViewProxy(Context appContext, String host, int port) {
System.setProperty("http.proxyHost", host);
System.setProperty("http.proxyPort", port + "");
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", port + "");
try {
Class applictionCls = Class.forName("android.app.Application");
Field loadedApkField = applictionCls.getDeclaredField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
for (Object receiverMap : receivers.values()) {
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
Class clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
/*********** optional, may be need in future *************/
final String CLASS_NAME = "android.net.ProxyProperties";
Class cls = Class.forName(CLASS_NAME);
Constructor constructor = cls.getConstructor(String.class, Integer.TYPE, String.class);
constructor.setAccessible(true);
Object proxyProperties = constructor.newInstance(host, port, null);
intent.putExtra("proxy", (Parcelable) proxyProperties);
/*********** optional, may be need in future *************/
onReceiveMethod.invoke(rec, appContext, intent);
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
I hope it can help you.
Note: The Context parameter should be an Application context as the parameter name showed, you could use your own implemented Application instance which extend Application.
I've made some changes to #xjy2061's answer.
Changes are:
getDeclaredField to getField --> You use this if you declared your own application class. Else it won't find it.
Also, remember to change "com.your.application" to your own application's class canonical name.
private static boolean setKitKatWebViewProxy(WebView webView, String host, int port) {
Context appContext = webView.getContext().getApplicationContext();
System.setProperty("http.proxyHost", host);
System.setProperty("http.proxyPort", port + "");
System.setProperty("https.proxyHost", host);
System.setProperty("https.proxyPort", port + "");
try {
Class applictionCls = Class.forName("acr.browser.barebones.Jerky");
Field loadedApkField = applictionCls.getField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
for (Object receiverMap : receivers.values()) {
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
Class clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
/*********** optional, may be need in future *************/
final String CLASS_NAME = "android.net.ProxyProperties";
Class cls = Class.forName(CLASS_NAME);
Constructor constructor = cls.getConstructor(String.class, Integer.TYPE, String.class);
constructor.setAccessible(true);
Object proxyProperties = constructor.newInstance(host, port, null);
intent.putExtra("proxy", (Parcelable) proxyProperties);
/*********** optional, may be need in future *************/
onReceiveMethod.invoke(rec, appContext, intent);
}
}
}
return true;
} catch (ClassNotFoundException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (NoSuchFieldException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (IllegalAccessException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (IllegalArgumentException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (NoSuchMethodException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (InvocationTargetException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
} catch (InstantiationException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Log.v(LOG_TAG, e.getMessage());
Log.v(LOG_TAG, exceptionAsString);
}
return false;
}
I am creating a cordova android application, and couldn't figure out why ajax requests to internal hosts on my company's network were failing on KitKat. All native web requests succeeded, and all ajax requests on android versions below 4.4 succeeded aswell. The ajax requests only failed when on the internal company wifi which was even more perplexing.
Turns out KitKat uses a new chrome webview which is different from the standard webviews used in previous android versions. There is a bug in the version of chromium that kitkat uses where it doesn't respect the proxy exclusion list. Our company wifi sets a proxy server, and and excludes all internal hosts. The ajax requests were ultimately failing because authentication to the proxy was failing. Since these requests are to internal hosts, it should have never been going through the proxy to begin with. I was able to adapt xjy2061's answer to fit my usecase.
Hopefully this helps someone in the future and saves them a few days of head banging.
//Set KitKat proxy w/ proxy exclusion.
#TargetApi(Build.VERSION_CODES.KITKAT)
public static void setKitKatWebViewProxy(Context appContext, String host, int port, String exclusionList) {
Properties properties = System.getProperties();
properties.setProperty("http.proxyHost", host);
properties.setProperty("http.proxyPort", port + "");
properties.setProperty("https.proxyHost", host);
properties.setProperty("https.proxyPort", port + "");
properties.setProperty("http.nonProxyHosts", exclusionList);
properties.setProperty("https.nonProxyHosts", exclusionList);
try {
Class applictionCls = Class.forName("android.app.Application");
Field loadedApkField = applictionCls.getDeclaredField("mLoadedApk");
loadedApkField.setAccessible(true);
Object loadedApk = loadedApkField.get(appContext);
Class loadedApkCls = Class.forName("android.app.LoadedApk");
Field receiversField = loadedApkCls.getDeclaredField("mReceivers");
receiversField.setAccessible(true);
ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
for (Object receiverMap : receivers.values()) {
for (Object rec : ((ArrayMap) receiverMap).keySet()) {
Class clazz = rec.getClass();
if (clazz.getName().contains("ProxyChangeListener")) {
Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class, Intent.class);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
/*********** optional, may be need in future *************/
final String CLASS_NAME = "android.net.ProxyProperties";
Class cls = Class.forName(CLASS_NAME);
Constructor constructor = cls.getConstructor(String.class, Integer.TYPE, String.class);
constructor.setAccessible(true);
Object proxyProperties = constructor.newInstance(host, port, exclusionList);
intent.putExtra("proxy", (Parcelable) proxyProperties);
/*********** optional, may be need in future *************/
onReceiveMethod.invoke(rec, appContext, intent);
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
You would call the method above as follows:
First import this library at the top of your file.
import android.util.ArrayMap;
Then call the method
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
//check first to see if we are running KitKat
if (currentapiVersion >= Build.VERSION_CODES.KITKAT){
setKitKatWebViewProxy(context, proxy, port, exclusionList);
}
https://android.googlesource.com/platform/external/chromium/+/android-4.4_r1/net/proxy/proxy_config_service_android.cc
Has methods to set the proxy. I am still trying to figure out how to invoke this from Java code. Pointers?
https://codereview.chromium.org/26763005
Guess from this patch, you'll be able to set up a proxy again in the near future, perhaps.
Had some issues with the provided solution on some devices when loading page from onCreate right away after setting the proxy configuration. Opening the web page after some small delay solved the problem. Seems like the proxy config needs some time to get effective.