Read file in grails - java

So I have a few .drlt files (normal txt files that serves me as templates for rule engine) and
I need to read them and put in to some static string variable in bootstrap of application.
I just cannot figure out where to put it in grails application and how to read them.
I've tried put them to src/java and read them from src/grails, domain, service etc. None of that worked. The only thing that worked is to put it into grails-app/conf and read them like this:
def classLoader = Thread.currentThread().contextClassLoader
def fileReader = classLoader.getResourceAsStream('my-file.drlt').newReader()
But I don't want to put my template files in config directory.
I've read many posts and 'solutions' for this problem but non of them are good solutions. Is it really possible that this is unable to do nice in such a stable framework as Grails?
Thanks for any help,
Ivan

Since Grails is a well structured Spring application you can take advantage of Resource and ResourceLoader to load your text file. The grailsResourceLocator makes using these quite simple (be sure to inject it into your bean). Using these classes you can locate your file within the src/java or src/groovy directories and treat it as any other class resource.
So for example, if your file is in src/java/com/example/textfile.txt then your can access it as a File using grailsResourceLocator.findResourceForURI('classpath:/com/example/textfile.txt').getFile()
A detailed example can be found within this blog post and the API documentation for Resource may help as well.
This is the correct way to handle resources within your Grails application.

Related

Serve static files in openLiberty

I am trying to serve a static file on OpenLiberty application but haven't found a straightforward way to do so.
At first I simply put the file in the src/resources and webapp/META-INF folder but it seems that this is not enough.After a bit of research I found a few approaches which all didn't fit my needs.
For instances [0] suggested placing the file in the dropin folder. But this is a folder in the deployed app and I need the file within the source root folder at build time.
Another post [1] suggested created a custom config file but that is for WAS only.
When I started to look more broadly (JaxRS) there was even the idea to create Rest endpoint that loads the file from the classpath [2]. This idea, while being plausible, seems to complicated for what I intend to accomplish. I even found a config option (fileServingEnabled) in the official documentation [3] but the description is thin on how to properly configure it.
Is it possible to do that with plain OpenLiberty or do I have to go another way in order to achieve that?
[0] How do I display an HTML file using Websphere Liberty?
[1] https://www.ibm.com/mysupport/s/question/0D50z00005pgfiVCAQ/how-serve-static-html-files?language=en_US
[2] How to serve static content with JAX-RS?
[3] https://openliberty.io/docs/21.0.0.9/reference/config/webContainer.html

Reading a JSON File in a Java Class of a Dynamic web project

I want to read a JSON file to in a java class of a dynamic web project (not in a servlet).
Can someone tell how to read the resource(JSON file) which is placed in WEB-INF folder of the project.
Can someone tell how to achieve this?
Two basic options.
a) use ServletConfig.getServletContext() to obtain the currently active servlet context. This can only work IF the code is executed as part of an actual servlet request, otherwise there simply is no active servlet context to speak of.
b) actually put the file on the classpath, so that it ends up in WEB-INF/classes or inside a jar in WEB-INF/lib; then you can load it from any class in your application using getClass().getResourceAsStream() or getClass().getClassLoader().getResourceAsStream(), at any time.
Option b) has the added benefit of also working in any type of Java application so it is nice and portable. It can also work in a unit test for example.

Accessing properties from application.properties in a non Controller class

http://www.javadb.com/using-a-message-handler-to-alter-the-soap-header-in-a-web-service-client
In the above mentioned example we have hard coded TestUser(username) and TestPassword(password) in the message handler class.I want to externalize these values.
After some research I was not able to implement #Autowired and #value .Please help me out with this
If your .properties file is saved somewhere on the local hard-drive and it is one of the KPL (Key Project Locations), you can simply do this:
Properties propObj = new Properties ();
FileInputStream fis = new FileInputStream("relative path to your file");
propObj.load(fis);
Once you do this, simply use getProperty() or setProperty() to access/mutate desired properties. There is also another way to use the loadFromXML() method if your choice of file is an xml file. I hope this solves your problem because it sounds like you simply having trouble to load a file regardless of being in a controller class. If I am right, then you will find endless examples online that tells you to do merely what I wrote above :)
When using things like #Autowire remember that you have to annotate before the beginning of the target class with #ContextConfiguration("location_of_file.xml"). Getting the correct relative path may be a bit tricky when specifying an applicationContext file. See here and follow other links to find out more about this.
BTW one thing you have to remember that application properties are somewhat internal to an application and for this reason, they are set in a .properties file outside the source files so that it can be run without changing source code (correct me somebody if I am talking bollocks!).
If you are using build automation tools such as Maven or Ivy, there is a way to make sure that your application properties are set using the a) POM and b) applicationContext.xml files. In this way, the application is even more decoupled from breaking down in case a relative path doesn't work out to be the some on a target computer. If you want this, you have to be careful about setting the filters in POM. I haven't personally done this by hand, but we were working on a project a few months ago when a colleague of mine set the filer in front of me. I remember this because everything was failing due to incorrect filter setting. Sorry, but you have to find it out yourself using uncle Google!

Shipping Java code with data baked into the .jar

I need to ship some Java code that has an associated set of data. It's a simulator for a device, and I want to be able to include all of the data used for the simulated records in the one .JAR file. In this case, each simulated record contains four fields (calling party, called party, start of call, call duration).
What's the best way to do that? I've gone down the path of generating the data as Java statements, but IntelliJ doesn't seem particularly happy dealing with a 100,000 line Java source file!
Is there a smarter way to do this?
In the C#/.NET world I'd create the data as a separate file, embed it in the assembly as a resource, and then use reflection to pull that out at runtime and access it. I'm unsure of what the appropriate analogy is in the Java world.
FWIW, Java 1.6, shipping for Solaris.
It is perfectly OK to include static resource files in the JAR. This is commonly done with properties files. You can access the resource with the following:
Class.getResourceAsStream ("/some/pkg/resource.properties");
Where / is relative to the root of the classpath.
This article deals with the subject Smartly load your properties.
Sure, just include them in your jar and do
InputStream is = this.getClass().getClassLoader().getResourceAsStream("file.name");
If you put them under some folders, like "data" then just do
InputStream is = this.getClass().getClassLoader().getResourceAsStream("data/file.name");

Using the ClassLoader method to retrieve all resources under classes as Input Streams

My problem is one that you would think is quite common, but I haven't so far managed to find a solution.
Building a Java web app under Tomcat 5.5 (although a requirement is that it can be deployed anywhere, like under a WebLogic environment, hence the loading resources as streams requirement). Good practice dictates that resource files are placed under WEB-INF/classes and loaded using the ClassLoader's getResourceAsStream() method. All well and good when you know the name of the resource you want to load.
My problem is that I need to load everything (including recursively in non-empty sub-directories) that lives in a subdirectory of classes.
So, for example, if I have the following under WEB-INF/classes:
folderX/folderY
folderX/folderY/fileA.properties
folderX/fileB.properties
I need the fileA.properties and fileB.properties classes to be loaded, without actually knowing their names before the application is started (ie I need the ability to arbitrarily load resources from any directory under WEB-INF/classes).
What is the most elegant way to do this? What object could I interrogate to find the information I need (the resource paths to each of the required resources)? A non-servlet specific solution would be best (keeping it all within the class loading framework if possible).
Thanks in advance!
As far as I am aware, there is no such ability, since the classloader only attempts to load things it is asked for. It doesn't pre-fetch all items on the classpath, or treat them as a directory structure.
The way I would solve the problem is create a directory listing in a text file of all relevant resources at build time and include that in the war, and then walk it through that way.
You can do that with some tricks :)
Get the resource as URL, extract the protocol :
file protocol - get the URL path and you have a folder, scan for files.
jar/zip protocol - extract the jar/zip path and use JarFile to browse the files and extract everything under your path/package.

Categories