MissingResourceException , can't find bundle for basename, locale en-us in quarkus native image - resourcebundle

I have a basename.properties file in resources folder. Whenever I try to load a bundle using
File file = new File(String.valueOf(resourceBundlePath));
URL[] urls = {file.toURI().toURL()};
ClassLoader loader = new URLClassLoader(urls);
resourceBundle = ResourceBundle.getBundle(VALIDATION_MESSAGES, locale, loade);
in dev mode, resourceBundle variable is fetching corresponding locale file and if not present, it picks the default basename.properties file without throwing any exception. But, in GraalVM native image, it throws Missing resource exception, Can't find bundle for base name and locale en-us.
If the locale doesn't exist in the external classloader, it is not performing fallback to just basename.properties file. Could someone help?

Related

Vaadin Flow 14, Jetty embedded and static files

I'm trying to create app based on Jetty 9.4.20 (embedded) and Vaadin Flow 14.0.12.
It based on very nice project vaadin14-embedded-jetty.
I want to package app with one main-jar and all dependency libs must be in folder 'libs' near main-jar.
I remove maven-assembly-plugin, instead use maven-dependency-plugin and maven-jar-plugin. In maven-dependency-plugin i add section <execution>get-dependencies</execution> where i unpack directories META-INF/resources/,META-INF/services/ from Vaadin Flow libs to the result JAR.
In this case app work fine. But if i comment section <execution>get-dependencies</execution> then result package didn't contain that directories and app didn't work.
It just cannot give some static files from Vaadin Flow libs.
This error occurs only if i launch packaged app with ...
$ java -jar vaadin14-embedded-jetty-1.0-SNAPSHOT.jar
... but from Intellij Idea it launch correctly.
There was an opinion that is Jetty staring with wrong ClassLoader and cannot maintain requests to static files in Jar-libs.
The META-INF/services/ files MUST be maintained from the Jetty libs.
That's important for Jetty to use java.util.ServiceLoader.
If you are merging contents of JAR files into a single JAR file, that's called a "uber jar".
There are many techniques to do this, but if you are using maven-assembly-plugin or maven-dependency-plugin to build this "uber jar" then you will not be merging critical files that have the same name across multiple JAR files.
Consider using maven-shade-plugin and it's associated Resource Transformers to properly merge these files.
http://maven.apache.org/plugins/maven-shade-plugin/
http://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html
The ServicesResourceTransformer is the one that merges META-INF/services/ files, use it.
As for static content, that works fine, but you have to setup your Base Resource properly.
Looking at your source, you do the following ...
final URI webRootUri = ManualJetty.class.getResource("/webapp/").toURI();
final WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));
That won't work reliably in 100% of cases (as you have noticed when running in the IDE vs command line).
The Class.getResource(String) is only reliable if you lookup a file (not a directory).
Consider that the Jetty Project Embedded Cookbook recipes have techniques for this.
See:
WebAppContextFromClasspath.java
ResourceHandlerFromClasspath.java
DefaultServletFileServer.java
DefaultServletMultipleBases.java
XmlEnhancedServer.java
MultipartMimeUploadExample.java
Example:
// Figure out what path to serve content from
ClassLoader cl = ManualJetty.class.getClassLoader();
// We look for a file, as ClassLoader.getResource() is not
// designed to look for directories (we resolve the directory later)
URL f = cl.getResource("webapp/index.html");
if (f == null)
{
throw new RuntimeException("Unable to find resource directory");
}
// Resolve file to directory
URI webRootUri = f.toURI().resolve("./").normalize();
System.err.println("WebRoot is " + webRootUri);
WebAppContext context = new WebAppContext();
context.setBaseResource(Resource.newResource(webRootUri));

JavaFX jar doesnt read .properties file

I have developed a javafx application that reads the database configuration properties from a ".properties file".When i run the app in eclipse everything works fine.The problem is when running the app from the generated executable jar,it throws me a NullPointerException because it cant read the ".properties file".
The code is :
FileInputStream fis=new FileInputStream("resources/META-INF/db/db.properties");
Properties properties = new Properties();
properties.load(fis);
I searched about this and i saw some examples of using InputStream :
Properties pp = new Properties();
InputStream is = getClass().getClassLoader().getResourceAsStream("errors.properties");
pp.load(is);
But still doesnt work.Any idea?strong text
Try creating a folder that you always have with you Jar. The folder name should be resources. This folder should have a folder named META-INF. META-INF should have a folder named db. Finally, db should have the db.properties file in it.

Pyexcel, loading a file to create a book in memory

This is solved; thanks to #vmontco's solution: I was missing MEDIA_URL, now it works perfectly.
----------original question below-----------
I welcome suggestions from every angle; I am fairly new to Django and Python. I'm sure I am missing something simple.
Using a Model Form, with a FileField, I upload and save an Excel file to a folder structure under MEDIA_ROOT. This works.
I want to read that same file later to perform operations using Pyexcel. This is where I am stuck. I am attempting to upload the file using the FileField stored in the DB.
This is where I have problems, and I am not sure if am misunderstanding MEDIA_ROOT, or some other aspect of Django.
When I pass the pk to the 2nd view, I then instantiate an object based on the Model. It has the FileField 'docfile', which I am trying to use to access the file to do some operations using Pyexcel,
here is the FileField declaration from models.py:
docfile = models.FileField(
verbose_name="Choose file to upload:",
upload_to='Excel_CSV_Assets/%Y/%m/%d')
EDIT: If I hard-code the pth to the file like this, everything works, including operations afterwards:
thedocfile='site_static/site/original_assets/Excel_CSV_Assets/2016/04/23/Animals_oglc4DV.xlsx'
book=pyexcel.get_book(file_name=thedocfile)
:END OF EDIT
Here is the code from the 2nd view, where I attempt to read the file into memory, and make a 'book' class object using Pyexcel. I am stuck here:
asset = Excel_CSV_Asset.objects.get(id=assetid)
book=pyexcel.get_book(file_name=asset.docfile)
Here is my error description:
Here is the info right at where my code breaks:
Although it says "Wrong filename", I can see the file is in the folder:
I'm able to open the file by double-clicking; the file is not corrupted.
EDIT:
If I cast the 'asset.docfile' to str, like so:
asset = Excel_CSV_Asset.objects.get(id=assetid)
book=pyexcel.get_book(file_name=str(asset.docfile))
I get a different error:
[Errno 2] No such file or directory: 'Excel_CSV_Assets/2016/04/23/Animals_oglc4DV.xlsx'
...but this is the correct directory, located beneath the MEDIA_ROOT file structure.
Here is settings.py MEDIA_ROOT:
MEDIA_ROOT = 'site_static/site/original_assets/'
Here is urls.py:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^e/', include('excel_to_mongo.urls')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
Here is the url.py of that app:
url(r'^efactory/(?P<assetid>\d+)/$', 'display_sheet_column_choices', {}),
I think your problem is that you don't fully understand the media files management with Django.
What are media files?
Media files are all the files that are user-uploaded (at running time).
You must not mistake them with Static files that are assets needed by your project to work and that you add at development time (CSS, background picture and JS files for instance).
You shouldn't mix them because they are managed differently by the server and that it could lead to security problems (cf. the warning here):
Static files management :
You put your static files as a part of the code either in one static subdirectory from the installed django applications, either in one of the locations you added to STATICFILES_DIRS.
Static files have to be gathered before starting the server by calling ./manage.py collectstatic, this command will collect (copy) the static files into the a directory (STATIC_ROOT's value).
You then have to set STATIC_URL to choose with wich url you should serve your static files. An usual choice would be /static/. To access the static file you should then try to reach /static/path/to/static/file/in/static_root/dir.
Media files management :
Your media files are added at running time. They are stored in the MEDIA_ROOT location that has to be an absolute path. Hence the fact I suggested you to join the BASE_DIR value (an absolute path) and the subdir you would choose with something like :
MEDIA_ROOT = os.path.join(BASE_DIR, "/media/subdir")
You then have to set an URL for your media files, by using the MEDIA_URL variable. To access your media files, the urls will start with the value you choose :
MEDIA_URL = '/media/'
Then, add this to your urls.py file :
if settings.DEBUG:
urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
With the current example, your mymediafile.txt will be located at /path/to/your/project/media/subdir/path/in/media/root/mymediafile.txt and served at http://127.0.0.1:8000/media/path/in/media/root/mymediafile.txt.
But this is suitable only for a development use as told here. And this would work only for DEBUG == TRUE
For a production use, you should consider deploying your media files with your http server (apache for instance).
Conclusion :
Take the time to understand this. Because I suspect you don't really understood what you did and this lack of understanding could lead to future bugs and errors.

XSLT document() relative path resolving to IIS.exe

I have a .NET WebApi project with two files, both of which have been marked as embedded resources and are deployed with the application. The files are also both in the same directory in the deployed application:
./xsl/transform.xslt
./xsl/schema.xsd
The xslt file needs to load the xsd file via the document() function:
<xsl:template match="*[not(local-name() = document('schema.xsd')//xs:element/#name)]" />
<xsl:template match="#*[not(local-name() = document('schema.xsd')//xs:attribute/#name)]" />
Unfortunately, I'm getting an exception at runtime that indicates that the relative path being resolved is the program files directory for IIS and not the directory where transform.xslt is located:
{
"Message": "An error has occurred.",
"ExceptionMessage": "An error occurred while loading document 'schema.xsd'. See InnerException for a complete description of the error.",
"ExceptionType": "System.Xml.Xsl.XslTransformException",
"StackTrace": "<ommitted>"
"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Could not find file 'C:\\Program Files (x86)\\IIS Express\\schema.xsd'.",
"ExceptionType": "System.IO.FileNotFoundException",
"StackTrace": "<omitted>"
}
}
I don't want to use an absolute path here because I don't want to become overly dependent on the environment the application is deployed into. Is there anyway to force the relative path source from the same directory that transform.xslt is deployed into at runtime?
For reference, the absolute path to the xslt file at runtime was:
C:\\MyFolder\\MyCode\\MyProject\\Web\\bin\\xsl\\transform.xslt
EDIT:
As requested, the following is (roughly) the code that is used to load the xslt from the manifest resource stream and run the transform. This code is unwrapped from several different custom packages to boil it down into core libraries, so don't worry about the stream management. I promise the real code is much safer:
XmlReader input = this.GetInput();
Stream ouput = new MemoryStream(4096);
Stream stream = typeof(ClassUsingTransform).Assembly.GetManifestResourceStream("transform.xslt");
MemoryStream mStream = new MemoryStream(stream.ToByteArray());
var navigator = new XPathDocument(mStream).CreateNavigator();
XslCompiledTransform processor = new XslCompiledTransform();
processor.Load(navigator, XsltSettings.TrustedXslt, new XmlUrlResolver());
processor.Transform(input, new XsltArgumentList(), output);
The XmlUrlResolver could not be unwrapped into builtins easily, but the type used inherited from XmlUrlResolver and didn't appear to modify any of the builtin settings. Most of the work done in the derived classes seemed to focus on performance optimizations. If anyone thinks the implementation here is important, I can try to unwrap that class a bit better.
The XsltArgumentList used was also a derived type, but the argument list is empty as far as I can tell.

log4j configuration in jar which is used by another application already using log4j

My problem is that i'm trying to set up log4j to log into a file from my jar. This jar is used by an application which already uses log4j. My jar is made as maven package shipped with log4j. I'm trying to initialize log4j from property file as such:
"log4j.properties"
log4j.appender.FileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.FileAppender.File=${user.home}/.myproject/myproject.log
log4j.appender.FileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.FileAppender.layout.ConversionPattern=%d{yy-MM-dd HH:MM:ss,SSS} [%t] %-5p %c %x - %m%n
log4j.appender.FileAppender.MaxFileSize=5MB
#myproject is full package name
log4j.logger.myproject=,FileAppender
I've included this property file into resources of my jar. I'm loading it with code:
try {
InputStream inputStream = this.getClass().getClassLoader()
.getResourceAsStream("log4j.properties");
Properties properties = new Properties();
properties.load(inputStream);
inputStream.close();
PropertyConfigurator.configure(properties);
} catch (NullPointerException e) {
BasicConfigurator.configure();
throw new MyprojectException("log4j.properties not found", e);
} catch (IOException e) {
throw new MyprojectException("log4j.properties could not be loaded", e);
}
This code is working flawlessly when my jar is not used by an application which uses log4j. But it is, i get an empty log file or for some cases in some applications, no log file is created at all.
I've tried to add an appender manually, not with propertyconfigurator like this:
static org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Myproject.class);
SimpleLayout layout = new SimpleLayout();
FileAppender appender = new FileAppender(layout,"C:/out.log",true);
logger.addAppender(appender);
logger.setLevel(Level.DEBUG);
This seems to be working fine, but i'd really want to configure log4j from properties file instead.
I've read lots of threads about how log4j handles multiple instances. I've found out that i cannot alter log4j configuration loaded by properties once it's done by one application. Some have suggested i shall ship my own log4j jar and config and configure with propertyconfigurator, that's what i've tried and as you can see it didn't work. I'm curious why my second example is working and the first is not. How can i solve this problem?
notes:
I do not want to alter the log4jconfigs of the applications that use my jar file.
I've also found out that there is -Dlog4j.configuration system property that could be used, but my jar is not an executeable jar file, it gets loaded by Class.forName
Any help is appreciated,
Thanks in advance

Resources