I am using activejdbc 1.4.9. I created one jar (using maven) which has two ActiveJDBC Model Classes. I added the jar to the application. Application has three more model classes. When I compile and try to run the application (gradle based), activejdbc is instrumenting only 3 classes which are in application but not instrumenting the classes which are in jar. When I try to write the data into the two models which are in jar, It is throwing exception as
org.javalite.activejdbc.DBException: Failed to retrieve metadata from DB. Are you sure table exists in DB ?
Now I have certain doubts. Please help me to resolve and understand few things.
How instrumentation happens ?
When we create a jar, will it include instrumented classes ?
Why it is throwing this error ?
It is throwing this error in case classes have not been instrumented. This means that before placing your model classes into a jar file, you need to instrument them. Does not matter which build method you use though. This http://javalite.io/instrumentation explains what is instrumentation and how to do it. Instrumentation does not create jars, it merely adds some byte code into your classes. In all scenarios you need:
Write code :)
Compile
Instrument
after this, you can do any of the following:
run app using class files in the file system
package class files into jar file and use that on your classpath
package jar file into a larger app (WAR, EAR, RAR, etc.) and deploy your app
making sense?
Related
How can I add a custom loader to the executable jar?
At the moment i'm doing it manually by opening the jar file, pasting the class and re-signing it the end. -.-
Thanks in advance,
Pedro Silva
Executable jar restrictions
There are 2 types of restrictions that you need to consider when working with a Spring Boot Loader packaged application.
Zip entry compression
The ZipEntry for a nested jar must be saved using the ZipEntry.STORED method. This is required so that we can seek directly to individual content within the nested jar. The content of the nested jar file itself can still be compressed, as can any other entries in the outer jar.
System ClassLoader
Launched applications should use Thread.getContextClassLoader() when loading classes (most libraries and frameworks will do this by default). Trying to load nested jar classes via ClassLoader.getSystemClassLoader() will fail. Please be aware that java.util.Logging always uses the system classloader, for this reason you should consider a different logging implementation.
Alternative single jar solutions
If the above restrictions mean that you cannot use Spring Boot Loader the following alternatives could be considered:
Maven Shade Plugin
JarClassLoader
OneJar
Resource Link:
The executable jar format
spring boot loading jars (application dependencies and external file system jars)
Can anyone explain how Spring decides where to look for resources when one uses the ResourceLoader.getResource(...) method?
I am having a problem with a multi-module maven application built using Spring Boot whereby in my integration tests my code is able to find resources using resourceLoader.getResource("templates/") or even resourceLoader.getResource("classpath:templates/"). So far so good...
However, when the module is eventually packaged into the executable JAR and run with embedded Tomcat the resources can no longer be resolved. I also tried resourceLoader.getResource("classpath*:templates/") with no success.
What I find concerning is that when I add a logging statement to output the URL being used in the search i get a path to one of the other modules in the project (not the one that actually contains the resource in question). E.g: jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module1-0.0.1-SNAPSHOT.jar!/templates/ whereas I believe the resource is in jar:file:/Users/david/exmaple/target/spring-boot-0.0.1-SNAPSHOT.jar!/lib/module2-0.0.1-SNAPSHOT.jar!/templates/
The resource loader was obtained from an Autowired constructor param.
Thanks in advance for any hints.
Edit
Just in case it isn't clear or is of importance, my integration tests for the module in question aren't aware of the other module. I have module1, module2 and a spring-boot module which has dependencies on module1 & module2. Essentially, when I run the integration tests for module 2 the classpath isn't aware of module1 - so I suspect that this has something to do with why it works in the tests.
When you use classpath: or classpath*: prefix, internally, this essentially happens via a ClassLoader.getResources(…) call in spring.
The wildcard classpath relies on the getResources() method of the underlying classloader. As most application servers nowadays supply their own classloader implementation, the behavior might differ especially when dealing with jar files. A simple test to check if classpath* works is to use the classloader to load a file from within a jar on the classpath: getClass().getClassLoader().getResources("<someFileInsideTheJar>"). Try this test with files that have the same name but are placed inside two different locations. In case an inappropriate result is returned, check the application server documentation for settings that might affect the classloader behavior.
Do not use classpath: form as you have multiple classloader locations of templates/ .
Refer to: resources-classpath-wildcards
This is a kind of driving me nuts, I found some similar questions here on SO but I can't get it to work.
I have a multi project spring (web) project. It starts fine, but as soon as I want to query the db I get a
Nested in org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.apache.commons.dbcp.SQLNestedException:
Cannot create JDBC driver of class 'oracle.jdbc.OracleDriver' for connect URL 'jdbc:oracle:thin//server:1521:XE':
I tried many things: I made sure the ojdbc.jar is inside my project (not part of maven repo so I loaded it with gradle like
compile files('lib/websphere_apis.jar','lib/ojdbc14.jar')
in my sub (not web) or in my web project.
Which gets the jars inside war when I generate them with with gradle war
I tried adding the jars to the jettyRun configuration with
jettyRun {
additionalRuntimeJars = files('lib/ojdbc14.jar')
}
I'm a bit in doubt whether the files stmt is correct but still it doesn't work.
I also found on SO that I should put
providedRuntime files("$projectDir/../lib/ojdbc14.jar")
inside my webapp as a standard dependency but that still doesn't work for me. I have used postgres driver jars before which I could just include as a dependency.
With JDBC .jar files, if you are not careful about where you load the .jar on the classpath, you might get an error like what you are seeing. If you want to be sure, pass the .jar on the classpath as an argument to the main JVM that is calling the program. The reason is that you need to make sure the .jar class files are loaded in the "default JVM classloader". If you try to load JDBC .jars dynamically through other means ( perhaps even as OSGI) , or dynamically loaded by custom classloader like Tomcat has, then you could get class loader issues.
In the following senario
I'm wrapping an external jar file (read a dependency I've no control over) and wrapping this in a service to be exposed over RMI.
I'd like my service interface to also be exported as a maven dependency however as it will be returning classes defined in the dependency this means that the dependency itself will be used as a dependency of my service interface.
Unfortunatly the origional jar file contains many classes that are not relevant to my exposed service.
Is it possible to depend on just a few classes in that jar file in maven (possibly by extracting and repackaging the few classes that are relevant)?
uberbig_irrelevant.jar
com.uberbig.beans <-- Need this package or a few classes in it.
com.uberbig.everythingElse
Service project includes all of uberbig jar. But exposes a service BeanService which has a call which returns an insance of com.uberbig.beans.IntrestingLightWeightSerialiasbleBean.
Service interface project needs to have a bean definition that looks like
interface BeanFetcher {
public IntrestingLightWeightSerialiasbleBean fetchBeanById(long beanId);
}
So ideally my serviceInterface jar file would only include the BeanFetcher interface. The definition of IntrestingLightWeightSerialiasbleBean and any direct dependencies of IntrestingLightWeightSerialiasbleBean.
The project is for use internally and won't be publically exposed so there should be no problems repackaging so long as the repackaged bean definitions are binary and searially compatable with the external jar file.
Any Suggestions?
Possibly related question Maven depend on project - no jar but classes
Maybe I could use something from the dependency:copy section of the maven-dependency-plugin but I haven't figured out how to do that.
I think you got the plugin right, but not the goal. You should use dependency:unpack instead.
You should be able to use an inclusion filter to extract only the classes you need, and then repack them into your own jar. (The service interface jar if you do it in the service interface project, but you can just as well set up a separate project.)
Create your own repackaged jar and put it in your local repo. And hope you've actually identified all dependencies, accounting for reflection, etc. IMO not really worth it.
You may be able to do it automatically (with the associated increased risk) by using ProGuard/etc. to pull out unused classes etc. That could be done on your own artifact as well, for example, by making an all-in-one jar via jarjar/onejar/etc.
We have a very comfortable setup using JPA through Spring/Hibernate, where we attach a PersistenceUnitPostProcessor to our entity manager factory, and this post processor takes a list of project names, scans the classpath for jars that contain that name, and adds those jar files for scanning for entities to the persistence unit, this is much more convenient than specifying in persistence.xml since it can take partial names and we added facilities for detecting the different classpath configurations when we are running in a war, a unit test, an ear, etc.
Now, we are trying to replace Spring with Seam, and I cant find a facility to accomplish the same hooking mechanism. One Solution is to try and hook Seam through Spring, but this solution has other short-comings on our environment. So my question is: Can someone point me to such a facility in Seam if exists, or at least where in the code I should be looking if I am planning to patch Seam?
Thanks.
If you're running in a Java EE container like JBoss 6 (and I really recommend so), all you need is to package your beans into a jar, place a META-INF/persistence.xml inside it and place the jar into your WAR or EAR package. All #Entity annotated beans inside the jar will be processed.
For unit-testing, you could point the <jar-file> element to the generated .class output directory and Hibernate will also pick the Entities. Or even configure during runtime using Ejb3Configuration.addAnnotatedClass;
#see http://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/configuration.html