When is Class.forName needed when connecting to a database via JDBC in a web app? - mysql

According to this tutorial, calling Class.forName isn't needed anymore with JDBC 4.0+ drivers. I successfully followed the method in the example (just calling DriverManager.getConnection) for a stand-alone program using MySQL, but when I tried to connect to the exact same database from a class that was part of a web app running on Tomcat 7, it wouldn't work; instead I got a No suitable driver found exception.
The mysql-connector-java-5.1.18-bin.jar file was in tomcat\webapps\DatabaseProject\WEB-INF\lib, I triple checked, but it wasn't working, so I started trying things. I added a call to Class.forName and it worked. That was the only thing that changed.
Anyway my question is, does anybody know why this worked or what was going on here? My only theory is that I also have hsqldb.jar in tomcat\lib for another project and maybe somehow the drivers got confused? But I was under the impression that DriverManager is supposed to be able to tell automatically which driver to use, so that's not supposed to be an issue... Anyway if someone could enlighten me as to what's going on here, I'd really appreciate it.

JDBC4 drivers include a file:
META-INF/services/java.sql.Driver
in the jar which uses the ServiceProvider mechanism to register the Driver implementation with the JVM (see javadocs for java.util.ServiceLoader). That's why Class.forName is no longer necessary.
My guess is that this is a class loader issue. The ServiceLoader javadoc mentions that:
The provider must be accessible from the same class loader that was
initially queried to locate the configuration file; note that this is
not necessarily the class loader from which the file was actually
loaded.
I would try putting your driver in the tomcat\lib directory rather than your web app directory to see if that makes a difference (different class loader?).
If you launch your web app through an ide and set a breakpoint, once you hit the breakpoint, you can use the "evaluate expression" feature to execute: ServiceLoader.load(Driver.class). This will give you a ServiceLoader class which you can peek into to see which Drivers are registered. You can check if the mysql driver is there, where in the list it is, etc, which might help in figuring out the behaviour here.

Related

metadata tag not found with describeType in production

I am using describeType and am able to get all of the variable and accessor metadata tags just fine in local debug, local test suite or local air build. Our web app running this code also sees the metadata just fine in production (running with browser plugin). But, our production air desktop app throws my error "can't find metadata". When I added some logging code (being thoroughly confused LOL) I discovered that the metadata property in the XML from describeType is empty?!?
My only thought is that we use gradle and run a bunch of custom scripts during the actual build process... but HOW could that be either removing or making unreadable class metadata tags?
I've tried standard v/s custom tags, accessors v/s variables, describeType(instance) v/s describeType(class) and all of these give same result... all variations work everywhere every time except in production desktop build.
Anyone with ANY thoughts on this... please chime in. I've been pulling my hair out with this one!
Thanks!!!
so it turns out my "only thought" was the correct answer. after digging deeper I found that the keep-as3-metadata that was on our compiler options was not up to date in our grade build scripts and didn't include the tags we were using for this. Thank god!!! LOL.

cannot find member on object of runtimetype

I am currently working on a legacy web app which uses newtonsoft.json.dll version 1.3.0 and vb.net.
I added four new fields in the application. This source code is shared by another application and it posts into my application and it breaks it.
See image for error.
[]
The error is:
Could not find member x on object of type runtimetype.
The stacktrace breaks at:
newtonsoft.json.jsonserializer.setobjectmember(jsonreader reader,object target, type targettype, string membername)
I did some research. The folks reportedly solved such an issue by upgrading DLL version and didn't have a direct solution to fixing it via code change. I know its very old and the application is high impact any upgrade has huge ripple. However they are planning a rewrite of the application.
Can someone please share any ideas that i should pursue in order to solve this?.
I am expected to make it quick and under pressure.
https://smugmugc3.codeplex.com/workitem/10024
My problem is very similar to what is described in the link above.
I am going to upgrade my version of json converter after convincing my boss and I see that is the only way out of this problem.
After which I will update this thread if I find issues.

Any method to use dotConnect without compiling the licence?

Im trying to use this http://www.devart.com/dotconnect/mysql/ with Indusoft Web Studio to connect from Windows CE to a MySQL database as its the only solution Ive found. The connection works (from what I see in the logs) but then a error message saying "License not found" pops up. Besides having terrible support, Devart for some odd reason does not understand Im using another IDE besides Visual Studio to compile this project. They keep telling me I need to add the resource to the project when IWS has nothing like this.
I tried to decompile the DLL but I cannot find a method to jump pass the "License not found" message.
Has anyone got this to work with a already complied program and just put the DLL in the same folder as their exe?
Ive tried their .NET Compact Framework complier as well but it did not work either. Their support is like I mentioned terrible. One of (if not the) the worst Ive had to deal with in YEARS.

.NET 4.5 / Assemblies loading from remote resource without loadFromRemoteSources=true

After installing .NET 4.5 beta, I noticed that my calls to Assembly.LoadFrom with a network path succeed without explicitly specifying "loadFromRemoteSources=true" in the application configuration file (whereas with .NET 4.0 this used to result in "System.NotSupportedException: An attempt was made to load an assembly from a network location which would have caused the assembly to be sandboxed in previous versions of the .NET Framework.")
I wonder if this, if it indeed is new behaviour and not something special in my setups (I've not yet decompiled the respective reflection classes or debugged the loading process to examine the differences), is an intentional change in policy and will remain in the RTM version?
The docs don't seem to indicate this change in behaviour. http://msdn.microsoft.com/en-us/library/dd409252(v=vs.110).aspx. And I would have expected a notice of it.
If it does work this way, then you're granting full trust by default and invisibly to a potentially dangerous assemblies and I can't imagine that would be the order of the day.
Have you got it added to machine.config per chance?
Also I would create a small program and target it to the 4.0 platform and induce this exception. Then I would retarget it to 4.5 and see if indeed it's true. Then I'd move the binaries to another machine and test there.

Application configuration files for Glassfish/Java EE 5 web services

I am trying to write some simple Java web services so we can call Java code from .NET. So far, I got a proof-of-concept working under Glassfish. Pretty straightforward when the IDE does all the work.
Now I'm really bogging down on stuff in Java that should be really simple. For example, I want to externalize my configuration so I can change stuff like connection strings/usernames/application variables/etc without recompiling.
In .NET, you would just stick some strings in the web.config file in the root of the web site and use: ConfigurationManager.AppSettings["whateverIwant"];
I can get java.util.Properties to do what I want (from a standalone client), but I can't figure out where to put the .properties file and how to get the path to it from within the web service.
I need my approach to work within WebSphere Application Server as well. Thanks!
As others have mentioned, it greatly depends on the container, but almost always dynamic configurations are stored in a database instead of XML or .properties files.
As I see that this is just like a proof of concept, here's a quick and dirty solution: (don't do this for production code) use System Properties.
Disadvantage: with every change you need to reboot the container, but you don't need to recompile the app.
To use system properties in Glassfish you can go to the section "Configuration -> System Properties" and add properties there. Then from inside your application just call
String myValue = System.getProperty("myProperty");
To get the value. All java applications support these properties, but I don't know how to configure them in Websphere.
Alas, Java EE has a giant hole in the head when it comes to application configuration.
Your best bet is to either:
use JNDI to store config in the application server environment. This is hard to do portably, painful, and an absolute nightmare for the user to do any configuration. Configuration UI depends on which app server and version is in use and may be a command-line-only utility specific to that app server.
Use the Preferences API to store your configuration, and produce your own UI to edit it. This is OK ... except that you can't control when your settings are flushed and re-inited. Some app servers will do this when your app is re-deployed, which you probably don't want.
All in all, the situation absolutely stinks. There's no clean, sensible way for an app server to provide an app with a simple properties map and UI to edit it using the app server's admin tools.
I tried to work around this using web context parameters, but found that they too were buggy. Glassfish was ignoring more than the first web context parameter that was being set, and they were hard to access without having a servlet context so you couldn't really get to them easily across the whole app.
If anyone has a better answer I'd love to hear it, because the situation as it stands seems downright amazing for a spec that's been through several major iterations.
see also: Storing and editing configuration for Java EE applications
Application configuration is unfortunately container dependent. In general you access your configuration through JNDI. The approach I've recently used was the following:
Make a database available to your app (through JNDI, use the Glassfish database "wizard"). This is part is container dependent.
Create an entity bean that deserializes your settings from the database. The simple solution here is to have something like this:
#Entity
public class Setting {
#Id
private String name;
private String value;
...
}
Then it's a question of doing em.find(Setting.class, "whateveriwant").getValue(). Alternatively, you could create a single entity bean with all the settings as attributes.
Either way, this approach reduces the container dependency to a minimum.
The best solution I've found so far is "EAC4J (External Application Configuration For Java)". I've used successfully in many projects.
Put the following code in the contextInitialized method of a ServletContextListener:
ServletContext sc = sce.getServletContext();
Properties systemProps = System.getProperties();
String path = sc.getRealPath("WEB-INF/application.properties");
systemProps.load(new FileInputStream(path));
This reads from application.properties from the the WEB-INF folder of your web app when it starts. This will require a restart every time the configs change, but in my opinion, that is as it should be.