I faced with the problem:
Native Library Ltkrnx.dll already loaded in another classloader
during redeploy application(tomcat 8 server).
I also added check, but it's doesn't help me.
private void loadLibrary(LTLibrary library) {
if (!Platform.isLibraryLoaded(library)) {
Platform.loadLibrary(library);
}
}
Caused by: leadtools.RasterException: Native Library C:\LEADTOOLS 20\Bin\CDLL\x64\Ltkrnx.dll already loaded in another classloader
Are you using LEADTOOLS in 2 different web applications? If yes, the following answer might help you solve the problem:
java.lang.UnsatisfiedLinkError: Native Library XXX.so already loaded in another classloader
Since that question is about OpenCV, not LEADTOOLS, I will quote the relevant parts here (very slightly edited):
Now there's the restriction that a native library can only be loaded
in one class loader. Web applications use their own class loader so if
one web application has loaded a native library, another web
application cannot do the same. Therefore code loading native
libraries cannot be put in a webapp directory but must be put in the
container's (Tomcat) shared directory. When you have a class written
with the usual pattern above (loadLibrary in static initializer of
using class) it's enough to put the jar containing the class in the
shared directory. With .. the loadLibrary call in the web application
code however, the native library will still be loaded in the "wrong"
class loader and you will get the UnsatisfiedLinkError.
To make the "right" class loader load the native library you could
create a tiny class with a single static method doing only the
loadLibrary. Put this class in an extra jar and put this jar in the
shared Tomcat directory. Then in the web applications replace the call
to System.loadLibrary with a call to your new static method. This way
the class loaders for the .. native library will match and the native
methods can be initialized.
If your situation is different, or the suggestion there doesn’t help you, send the following information to support#leadtools.com and our support team will work with you to isolate the problem:
The details of this question (exception you’re getting, version 20 of LEADTOOLS, 64-bit, Tomcat 8)
Your LEADTOOLS product serial number (don’t post it here!). If you’re still evaluating and don’t have a serial number, just mention that.
What you’ve tried so far to solve the problem and what results that gave you (for example, the answer mentioned above).
Other details about your OS, IDE or programming environment in general.
Related
I have a WebSphere application that makes use of shared libraries. Whenever an update is made to any jar in the shared libraries path, the application making use of it need to be restarted to get the latest changes. Is it possible to make a WAS application reload the shared libraries without having to be restarted?
I'm using traditional WAS 8.5.5.16.
Short answer: No.
Long answer: There's a technical reason why you can't do that. Java class loaders don't generally support recreating Class objects that they've already defined - once you define a class, it's defined, and that's that for the life of the class loader (the first step in loadClass is "findLoadedClass", which searches for an existing version of the class you're loading). In order for Java to agree to load a new instance of a Class object, you need to create an entirely new class loader, and in a Java EE (or, at least, WAS) setting, that requires restarting the application.
I believe from your question that you're simply associating a normal shared library with your application, so this doesn't necessarily apply, but I'd note that if you use an isolated shared library (which has its own class loader) or a shared library loader configured on the server, even restarting the application is not enough, because those library loaders are created with the server, not with the applications, so they require a server restart to pick up changes.
No. They're only loaded once on the startup of the server.
I have written a common class which I want to use in separate Blackberry applications. This class is not in a separate project but just at a common location and I have linked the path of the common class in Java Build Path. I have added same common path to both of my BB applications and they builds and installs without any problem. When I run one application, it start running but when I run the other application, it gives error message "class xxx multiply defined" error and exits.
Any idea what is going wrong here. Thanks in advance
Regards,
Braj
BlackBerry doesn't work as other Java platforms. In BB Java, you can't have two classes with the same full qualified name, even if they live in different projects.
You'll have to rename one of them (either change the class name or the package name) for it to work.
In fact, the only platform where I have seen this restriction is BB. It is a real pain in the ass since you can't reuse a jar library in different projects without renaming it.
UPDATE:
This is the official article on the topic:
http://supportforums.blackberry.com/t5/Java-Development/Application-throws-quot-multiply-defined-quot-error-at-start-up/ta-p/501498
All applications in RIM OS run under one instance of Java Virtual Machine. And therefore it is allowed only one class with particular full qualified name. Adding another class with the same name will lead to failure upon running both of these classes.
There is a library thing, supported in RIM OS, but I do not recommend to use libraries in your project, unless it is very necessary.
It is because if you have several apps with the same library, but with different versions of libraries you may get the same error you reported in your question. And it is hard to manage libraries when you have many applications which use these libraries.
I recommend to copy source code of your library to the project you are working on. Copy via refactoring, to change all full qualified names of classes included in that library.
Thanks guys for replying. I have created a common library and put common code in that. Now I can use this library in different applications without any problem.
However, when I install my applications using BB desktop Manager, the library appears as part of first application but not in second application. I assume it is because, second application realizes that the library is already been included so doesn't need to include it again.
I have a piece of software, contained in a single .jar that is doing its job but sometimes I need to quickly push a bug fix necessitating replacing the .jar file in a central location, unfortunately if there is a currently running execution of this jar file if I replace it then it crashes with "class not found" error. I thought that once a jar file is executed the JVM will cache it in memory and won't do any reads from the disk but apparently this is not the case, how can (if possible at all) this be remedied?
EDIT:
The application is not web-based. It's normal Java SE.
JAR files are not loaded into memory in bulk, as other shared object libraries are. Their classes are loaded into memory on a demand basis, so if you remove a JAR file and a class lookup needs to occur, the file handle the class loader will be invalid (because the open file it referenced is now gone) and you will get an error.
Operating systems manage the file handles, so replacing an open file with a new copy is not going to fool anyone. You need to close the file first, which often can only be done by garbage collecting the class loader. If you are using the system class loader, then that means shutting down the JVM.
People have written frameworks to create custom class loaders that can be disposed independently of the system class loader; however, this does complicate class loading. While it can accomplish what you are asking, it cannot do so without restructuring your existing program to accommodate the lookup of classes in the framework's class loaders (and accommodating the loss and gain of class loaders over time).
If you want to try such a framework, see Christian's post. If you want to learn a bit more about how one project uses class loaders to facilitate its needs, take a peek under the covers of Apache's Tomcat, which restricts web applications within their own class loaders.
Often you might find that the correct answer really is to stop the service prior to deployment, and start it after deployment.
The only two possibilities I can think of are using JRebel or OSGi.
Is there a way to determine which classes are loaded from which JARs at runtime?
I'm sure we've all been in JAR hell before. I've run across this problem a lot troubleshooting ClassNotFoundExceptions and NoClassDefFoundErrors on projects. I'd like to avoid finding all instances of a class in JARs and using process of elimination on the code causing a CNFE to find the culprit.
Will any profiling or management tools give you this kind of information?
This problem is super annoying purely because we should have this information at the time the class gets loaded. There has to be a way to get to it, or record it and find it, yet I know of nothing that will do this, do you?
I know OSGi and versioned bundles/modules aim to make this a non issue... but it doesn't seem to be going away any time soon.
Note: I found this question is a subset of my question related to classes loaded from versioned jars.
Somewhat related, this post explains a strategy to search for a class within JARs (either under the current directory) or in your M2_REPO: JarScan, scan all JAR files in all subfolders for specific class
Also somewhat related, JBoss Tattletale
Passing the -verbose:class switch to the java command will print each class loaded and where it was loaded from.
Joops is also a nice tool for finding missing classes ahead of time.
From code you can call:
myObject.getClass().getProtectionDomain().getCodeSource()
(Note, getProtectionDomain may unfortunately return null (bad design), so "proper code" would check for that.)
There is an MBean for the JVM flag mentioned by Jason Day above.
If you are using JBoss, you can twiddle this on demand using JMX, if you add the native JMX MBean server to your config. Add the following -D's:
-Dcom.sun.management.jmxremote.port=3333
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djboss.platform.mbeanserver
-Djavax.management.builder.initial=org.jboss.system.server.jmx.MBeanServerBuilderImpl
-DJBOSS_CLASSPATH="../lib/jboss-system-jmx.jar"
And then you can see this setting under the java.lang:Classloading MBean and can cut it on/off on the fly. This is helpful if you only want it on while executing a certain piece of code.
There is also an MBean which will allow you to enter a fully qualified classname and see where it was loaded from in the class hierarchy. The MBean is called LoaderRepository and you'll want to invoke the displayClassInfo() operation, passing in the FQCN.
In WebSphere (WAS) you can use a feature called "Class Loader Viewer"
Enable the class loader viewer first by clicking Servers > Server Types > WebSphere application servers > server_name > Class loader viewer service, enable the service and restart the server.
Then you can go to Troubleshooting > Class Loader Viewer and searching for your class or package name.
https://www-01.ibm.com/support/knowledgecenter/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/ttrb_classload_viewer.html?lang=en
You can easily export a JMX operation to access package info for any loaded class in you process like:
public static final class Jmx {
#JmxExport
public static Reflections.PackageInfo getPackageInfo(#JmxExport("className") final String className) {
return Reflections.getPackageInfo(className);
}
}
and here is a simple unit test to export and invoke it:
#Test
public void testClassLocator() throws IOException, InstanceNotFoundException, MBeanException, ReflectionException {
Registry.export(Jmx.class);
Reflections.PackageInfo info = (Reflections.PackageInfo) Client.callOperation(
"service:jmx:rmi:///jndi/rmi://:9999/jmxrmi",
Jmx.class.getPackage().getName(),
Jmx.class.getSimpleName(), "getPackageInfo", Registry.class.getName());
System.out.println(info);
Assert.assertNotNull(info);
}
this is all based using some small utilities library from spf4j (http://www.spf4j.org)
you can see this code at and the test at
I wanted to add to my jdk6\jre\lib\security\java.policy file an interdiction to create some classes that are blacklisted by appengine. For example I want my local jvm to throw an exception when the application tries to instantiate javax.naming.NamingException.
It is possible?
I will try to explain my specific problem here. Google offers an service (GAE-google app engine) that has some limitations on what classes can be used. For example doesn't instantiate JNDI classes that are in javax.naming package. They also offer an testing server that can be used to tests this application on my machine, but this server allows such classes and can exacute the code. You find out that you used a blacklisted class only after you upload your application to google. I was thinking if such class blacklist enforcement couldn't be done on the development jvm. Else i'm thinking that this would be easy they might already provide such a policy file.
You could write a small loader application that creates a new, custom classloader. Your application classes could then be loaded using this classloader.
In the custom classloader, you can then throw ClassNotFoundException when your application tries to access a class that you want to blacklist.
You will need to overload the load() method. This method will be responsible for throwing the exception on your blacklisted classes ordelegating to the parent Classloader if the class is allowed. A sample implementation:
public Class loadClass(String name) throws ClassNotFoundException {
if(name.equals("javax.lang.ClassIDontLike")){
throw new ClassNotFoundException("I'm sorry, Dave. I'm afraid I can't do that.");
}
return super.loadClass(name, false);
}
(Of course, a real implementation can be way more sophisticated than this)
Because the classes of your application are loaded through this Classloader, and you are only delegating the loadClass() invokations to the parent classloader when you want to, you can blacklist any classes that you need.
I am pretty sure that this is the method that Google uses to blacklist classes in their server. They load every app in a specific Classloader. This is also similar to the way that Tomcat isolates the different Web Applications.
Wouldn't you rather get compilation errors than runtime errors while testing your program? You could configure your IDE or compiler to warn you when an undesired class is instantiated. I know AspectJ has some nice features for this: You can define compilation warnings/errors on join points and get feedback in e.g. Eclipse. To use this in Eclipse, you simply install the AspectJ plugin and write a suitable aspect. To get the errors while compiling from a command line or script, you would actually have to use the AspectJ compiler, but I doubt that you would need that.
The Java documentation lists all possible policy permissions here:
http://java.sun.com/javase/6/docs/technotes/guides/security/permissions.html
Class creation / loading is not mentioned, so I believe you cannot enforce this using a policy.
At any rate, why do you want to throw an exception when an exception class is loaded? Maybe you could explain your problem, then someone might be able to propose a solution.
Edit:
One way to prevent loading of certain classes would be to remove them from the JRE installation. Most system classes are contained in rt.jar in your JDK/JRE installation. You should be able to modify it with any ZIP-tool.
Just create a special installation of your JRE, and modify its rt.jar. That is an ugly hack, but should be OK for testing purposes...