Java - how to get properties file from other modules - java

In one of module 'scheduler' classes I need to use data from properties file from modules : backend, common end entity-managers (e.g). Properties file are held in (module)/src/main/resources. How to achieve that?

You can access them easily using the ClassLoader.
this.getClass().getClassLoader().getResourceAsStream("myproperties.properties");
This will return the stream to the file, even if the file is in a different jar file.
Remind: Modules should stay seperated, try changing your code to go without such dependencies. Is it possible to set the necessery values on schedular initialization instead of reading them in scheduler itself?

Below are the two options I can think of:
1) In eclipse, for scheduler module, add other modules (e.g. backend) as dependencies (R-click on project > Build Path > Configure Build Path > Projects > Add). This will add the classpath entries of the added projects in scheduler classpath. If you are using maven, you may have to add the projects as internal dependencies in pom.xml of scheduler module as well.
2) Externalize the properties file by putting it outside your project structure, somewhere on the filesystem - e.g. under C:\properties directory. Add this directory to your project classpaths for modules, which use the property file. You can do this in eclipse by (R-click on project > Build Path > Configure Build Path > Libraries > Add Variable). Also ensure that the directory is there on your classpath when you run your application. If you are running it as standalone java application, then add the path in -cp switch of java command. If you are running it in any container, add the directory to your container's classpath.

Related

Specify jndi.properties location outside built JAR

I'm using Intellij.
I have a jndi.properties file (used for connecting to a Wildfly instance).
By default, Maven includes this file inside the JAR , after build. This is not good, as the jndi.properties contains the URL and credentials to the Wildfly instance and in production these will be different.
I managed to exclude the jndi.properties file by placing it in a separate folder (called config), and then in Intellij -> Module Settings -> Sources I marked the config folder as Resources and Excluded. This way, when I run the application inside Intellij, it works fine. But when I build the JAR, even if I place a folder called config outside the JAR, I still get an exception because no jndi.properties file is found in the classpath.
The same happens if I declare the config folder in the Dependencies tab in the Module Settings.
I also tried specifying the classpath when I run the java cmd line tool, but it seems that -cp does not work along with -jar.
I know two alternatives, but I don't really like them: have jndi.properties in JAVA_HOME/lib (not good, it will be common for all applications) or at runtime (-Djava.naming.provider.url etc, not as clear as a configuration file in my opinion).
Is there any way I could specify the jndi.properties file location at runtime?

How is in the real world deployed Maven application?

I have a Java console application, till now it was developed in Netbeans IDE. When Netbeans builds application, it creates dist directory and builds an app into this directory as a jar archive and into dist/lib copies all dependencies. This this directory could be copied into final destination and run.
Now I'm trying to transfer this project into Maven. Everything goes ok, I can compile and package my app and a jar is created into target directory. I use maven-jar-plugin to set main class in manifest and maven-shade-plugin to package all sources into one jar file.
I would like to ask you how is such Maven project deployed in the real world? Should I use all target directory, copy it ad the final destination and run as I have been used to do with Netbeans? What are consequences when I don't use maven-shade-plugin - where are all libraries defined as dependencies located? I am asking, because in my testing project these libraries don't exist in target directory.
My question - I have a Java console application "A" packaged via Maven (without maven-shade-plugin) and Linux server "S" where this application should run. Can I copy all target directory manually to server "S" or is there some better / more automatic way how is this solved in the real world?
Simply copying over the target directory will not solve your problem. I have packaged many standalone applications using Maven and I have used Maven Assembly Plugin for it. You can create a distribution archive (zip, tar.gz) using the assembly plugin which your customer can unzip and start running.
It depends on you, how you want your target application directory structure (release). I usually end up with something like
bin/
conf/
lib/
log/
The bin directory contains a shell / batch script to run your program by calling your main class, setting appropriate classpath, providing relevant memory settings etc. I prefer using classworlds (which is used by Maven) to bootstrap my application and simplify writing of start scripts.
conf directory contains configuration files for your application as well as logging configuration files like log4j etc. This directory I add on classpath to make it easier to access configuration resources at runtime.
lib directory contains all the dependency jars a well as jar file for your code.
log is where your logging configuration will point to output log files.
Note that this structure is good for standalone server like applications. Also having a bin directory and run scripts allows you to add this directory to PATH on Windows / Linux to ensure you can run the application from anywhere.
If you are packaging a command line utility, simple shaded jar may work for you. Personally, I am not the biggest fan of java -jar application.jar
The question is too broad to be answered comprehensively, but I would like to provide an example of real-world maven deployment.
There are maven plugins for all major application servers. They have defined targets for local and remote deployment. One such plugin is the jboss-as-maven plugin. You can define the deployment properties (IP, port etc.) in your .pom or directly from command line, e.g.
mvn jboss-as:deploy -Dpassword=mypassword
There is also the cargo plugin that specializes in application deployment.

is Bootstrap configuration mandatory to run dynamic project in eclipse?

To run dynamic project in eclipse, I have already added required jars in project class path, some jars path are reference from other open project. even though it is throw class not found error. when I put that jars in bootstrap entries, it works fine.
So my questions are:
1) Is Bootstrap configuration mandatory to run dynamic project?
2) Why does it not find class path while running server?
3) How can I run my project without configuring Bootstrap entries?
It must not be put in the build classpath, neither under User entries, nor under Bootstrap entries.
It must be dropped inside the WebContent/WEB-INF/lib directory of your webapp project. Eclipse will detect them, automatically add them into the build path for you, and automatically include them into the WEB-INF/lib directory of the deployed webapp, since that's where the Java EE containers look for the libraries needed by a Java EE webapp.

Eclipse(STS)/Maven integration issues

I am working on a fairly big project that uses maven for dependency management. As part of this we are using Maven profiles to build and replace certain properties files that differ between test/dev/production environments.
To perform a build I would execute a Maven:build using the correct profile and mavens reactor would then build the projects in the correct order and store the jars in the .m2 folder, eg the domain jar first, then the service jar (with the domain jar included in its jar as a dependency) etc. This leads to a war file eventually with all the correct libs required by the war to run.
When eclipse performs its default build that it performs everytime you save a file the jars are not built with any profile, just a regular build.
When I then push the final war file to the server and it is exploded when the server starts up (started and deployed through eclipse) I get in the lib folder all the jars that maven had packaged into the war file but also all the jars that eclipse had built.
eg
lib/
domain.jar (built by eclipse)
domain.SNAPSHOT.1.0.jar (built by maven)
etc
Is there any way to prevent this from happening? This has the end consequence of there being two of every property file and only the order in which they are loaded determines which is used. A real hassle as different properties are used in different environments.
I found a slightly hacky solution to this problem.
In the web projects properties -> Deployment Assembly I modified the path for the offending jar files eg domain.jar from
WEB-INF/lib/domain.jar
to
WEB-INF/autogen/domain.jar
This leads to the eclipse generated jar files (with the wrong properties files) to be deployed to a folder that won't be loaded when tomcat starts. Not a perfect solution but it allows all the nice things of eclipse auto-building like code completion and error messages in the web project if the interface of the domain changes etc while also providing the correct profile when deployed.
Leaving this here for anyone else in this situation.

What is the Maven idiom for accessing configuration files?

For example suppose I'm using the standard project structure and have
src/main/config/config.xml
To access this I presume
new File("src/main/config/config.xml");
would be incorrect
There is no "Maven Idiom" for accessing configuration files. Maven is a build platform, not an execution platform. So the conventions for accessing configuration files that apply are really just the conventions of the Java platform that you are using; e.g.
the plain J2SE way of doing it, or
the J2EE and/or webapp way of doing it, or
the J2ME way of doing it, or
...
Maven only comes into the picture because you (presumably) have resource files in your project / version control that need to be included in the JAR or WAR or whatever artifacts that you are building. To get this to work in Maven, you simply need to understand how Maven copies non-Java files into the artifacts.
In the simple (JAR) case, the default behavior is to copy anything in src/main/resources/ into the JAR, with the same relative name; e.g. src/main/resource/foo/bar.xml becomes /foo/bar.xml in the JAR file.
For WAR files, the default is to copy anything src/main/webapp to into the WAR file. So if you wanted a file to be accessible in the webapp as a classpath resource with the name /foo/bar.xml you would put it in src/main/webapp/WEB-INF/classes/foo/bar.xml. (I'm assuming that you know how webapp classpaths work ... or that this isn't your use-case.)
A config file is just a resource on your classpath like any other, so use:
URL resource = getClass().getResource("config.xml");
You'll need to do the usual Use as Source Folder on your src/main/config folder for this to work in Eclipse with m2e.
I think config files should be in src/main/resources by default.

Categories

Resources