GithubHelp home page GithubHelp logo

h-thurow / simple-jndi Goto Github PK

View Code? Open in Web Editor NEW
62.0 62.0 18.0 1.25 MB

Access property files via JNDI lookups. Get a DataSource from JNDI.

License: BSD 3-Clause "New" or "Revised" License

Java 100.00%

simple-jndi's People

Contributors

giamma avatar h-thurow avatar vectro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

simple-jndi's Issues

Support common property names for SJDataSource

Simple-JNDI expects a parameter called "driver", but many other JNDI implementations, including TomCat, use driverClassName. Simple-JNDI should support that too, in order to allow drop-in of properties files.

Search classpath for properties files

In addition to searching a specific path on the filesystem, there should be a way to tell Simple-JNDI to search the classpath. That way configuration files can be dropped into the resources folder and Simple-JNDI can find them, no matter where they might be (e.g., in a JAR).

Is it possible to bind the BeanManager using the properties file?

Hello!

At the moment my project looks like this:

<dependencies>
  <dependency>
    <groupId>com.github.h-thurow</groupId>
    <artifactId>simple-jndi</artifactId>
    <version>0.23.0</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.weld.se</groupId>
    <artifactId>weld-se-core</artifactId>
    <version>3.1.5.Final</version>
  </dependency>
  <dependency>
    <groupId>javax.enterprise</groupId>
    <artifactId>cdi-api</artifactId>
    <version>1.2</version>
  </dependency>
</dependencies>
java.naming.factory.initial = org.osjava.sj.SimpleContextFactory
org.osjava.sj.jndi.shared = true
org.osjava.sj.root = config
@ApplicationScoped
public class Main
{
  @Inject 
  private BeanManager beanManager;
	
  public void init(@Observes ContainerInitialized event) throws NamingException 
  {  
    InitialContext ic = new InitialContext(); 
    ic.bind("java:comp/env/BeanManager", beanManager);
       	   
    BeanManager beanManager = (BeanManager) ic.lookup("java:comp/env/BeanManager");
    System.out.println(beanManager.toString());
   }
}

And it works as expected.

Now, instead of binding the beanManager in the Main class with ic.bind("java:comp/env/BeanManager", beanManager); I would like to do that in an according properties file. Is this possible? I found the examples for DataSources objects and the other Java types, but I'm a bit at loss at the moment. This is what I tried:

Using the following jndi.properties:

java.naming.factory.initial = org.osjava.sj.SimpleContextFactory
org.osjava.sj.jndi.shared = true
org.osjava.sj.root = config
org.osjava.sj.space = java:comp/env
org.osjava.sj.delimiter=/

Should the env.properties file be created unter the config or under the config/java/comp folder?
What should the env.properties file look like?

BeanManager=? // I'm not sure how to get the injected object from above here - do I have to search for some kind of factory method within the weld library which I can state here?
BeanManager/type=javax.enterprise.inject.spi.BeanManager // If I understand correctly this is not supported 

It would be great if you could give me some hints!

Unexpected Simple-JNDI exceptions on startup

Hello,
I'm using Simple-JNDI in a Spring Boot application. It works as expected, however, I get exception like the following one on startup:

2021-07-23 15:24:03.010 ERROR 1980 --- [ main] org.osjava.sj.jndi.MemoryContext : MemoryContext#lookup("spring/mvc/pathmatch/use-suffix-pattern"): Invalid subcontext 'spring' in context '': MemoryContext{namesToObjects={}, subContexts={java:comp=MemoryContext{namesToObjects={}, subContexts={env=MemoryContext{namesToObjects={}, subContexts={string=MemoryContext{namesToObjects={}, subContexts={jndi-entries=MemoryContext{namesToObjects={hibernate_batch_fetchsize=#CHANGE_ME#, ur_miseendepot_gatewaytimeout=#CHANGE_ME#, binary_cache=#CHANGE_ME#, ur_miseendepot_encodagefichier=#CHANGE_ME#, ur_miseendepot_handlertimeout=#CHANGE_ME#, ur_miseendepot_thread_worker=#CHANGE_ME#, ur_miseendepot_thread_master=#CHANGE_ME#}, subContexts={}, env={org.osjava.sj.root=src/main/resources/jndi, org.osjava.sj.colon.replace=--, java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, org.osjava.sj.delimiter=., jndi.syntax.direction=left_to_right, jndi.syntax.separator=/, org.osjava.sj.space=java:comp/env/string, org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@6f24ce45, nameInNamespace=java:comp/env/string/jndi-entries, nameLock=true}}, env={org.osjava.sj.root=src/main/resources/jndi, org.osjava.sj.colon.replace=--, java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, org.osjava.sj.delimiter=., jndi.syntax.direction=left_to_right, jndi.syntax.separator=/, org.osjava.sj.space=java:comp/env/string, org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@e881e46, nameInNamespace=java:comp/env/string, nameLock=true}}, env={org.osjava.sj.root=src/main/resources/jndi, org.osjava.sj.colon.replace=--, java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, org.osjava.sj.delimiter=., jndi.syntax.direction=left_to_right, jndi.syntax.separator=/, org.osjava.sj.space=java:comp/env/string, org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@657b3b, nameInNamespace=java:comp/env, nameLock=true}}, env={org.osjava.sj.root=src/main/resources/jndi, org.osjava.sj.colon.replace=--, java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, org.osjava.sj.delimiter=., jndi.syntax.direction=left_to_right, jndi.syntax.separator=/, org.osjava.sj.space=java:comp/env/string, org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@2cea921a, nameInNamespace=java:comp, nameLock=true}}, env={org.osjava.sj.root=src/main/resources/jndi, org.osjava.sj.colon.replace=--, java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, org.osjava.sj.delimiter=., jndi.syntax.direction=left_to_right, jndi.syntax.separator=/, org.osjava.sj.space=java:comp/env/string, org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@65753724, nameInNamespace=, nameLock=false}

Here I can see the JNDI entries I defined via the configuration files together with the configuration properties, which is fine, but there are also "Invalid subcontext spring". What am I supposed to do in order to get rid of these exceptions ?

Many thanls in advance.

Nicolas

ENC problem

Hi,

I am trying to load:

InitialContext ic = new InitialContext();
ic.lookup("java:jboss/datasources/my_ds");

But I get the error Invalid subcontext 'java:jboss' in context ''

Content of the src/test/resources/jndi.properties file:

java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=src/test/resources/jndi
org.osjava.sj.delimiter=/
org.osjava.sj.space=java
org.osjava.sj.jndi.shared=true

Content of the src/test/resources/jndi/jboss/datasources.properties file:

my_ds.type=javax.sql.DataSource
my_ds.driver=com.mysql.jdbc.Driver
my_ds.url=jdbc:mysql://localhost:3306/my_ds
my_ds.user=xxx
my_ds.password=xxx

What is wrong? Thanks!

Need code review

Hi - I used Simple-JNDI in my project and built two JUnit 5 extensions for it, one to enable JNDI for an entire test class and another to enable JNDI for a single test method.

Would someone connected to Simple-JNDI be willing to review it? The pull request is here:
eeverman/andhow#537

The reason for creating these that it makes it so easy to use JNDI in a test and clean up after the test is done. For instance, here are the two tests that test the extension:
EnableJndiForThisTestMethodTest
EnableJndiForThisTestClassTest

I would be willing to contribute this to the Simple-JNDI project if you are interested.

Thank you,
Eric Everman

Simple-JNDI alongside Tomcat 8

I'm trying to use Simple-JNDI with Tomcat 8 so I can use a different connection pool with Eclipselink (JPA) without having to configure the JNDI resource in Tomcat itself.

This answer on stackoverflow indicates that it was working with Tomcat 6 at least: https://stackoverflow.com/a/13936449/3375325

I'd like to use HikariCP instead of Eclipselink's internal connection pooling, so what I do is create a HikariDataSource and try to bind it to a name, e.g. jdbc/OracleHikariDatasource in my WebListener's contextInitialized method. Unfortunately it already fails when calling new InitialContext() with the following RuntimeException:

java.lang.RuntimeException: Illegal node/branch clash. At branch value 'Property' an Object was found: [TEST, /logfiles/TEST/webapp]
    at org.osjava.sj.loader.JndiLoader.createSubContexts(JndiLoader.java:310) ~[simple-jndi-0.14.0.jar:?]
    at org.osjava.sj.loader.JndiLoader.jndiPut(JndiLoader.java:290) ~[simple-jndi-0.14.0.jar:?]
    at org.osjava.sj.loader.JndiLoader.load(JndiLoader.java:223) ~[simple-jndi-0.14.0.jar:?]
    at org.osjava.sj.loader.JndiLoader.loadDirectory(JndiLoader.java:125) ~[simple-jndi-0.14.0.jar:?]
    at org.osjava.sj.loader.JndiLoader.loadDirectory(JndiLoader.java:82) ~[simple-jndi-0.14.0.jar:?]
    at org.osjava.sj.SimpleJndi.loadRoot(SimpleJndi.java:78) ~[simple-jndi-0.14.0.jar:?]
    at org.osjava.sj.SimpleContextFactory.getInitialContext(SimpleContextFactory.java:72) ~[simple-jndi-0.14.0.jar:?]
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684) ~[?:1.8.0_131]
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313) ~[?:1.8.0_131]
    at javax.naming.InitialContext.init(InitialContext.java:244) ~[?:1.8.0_131]
    at javax.naming.InitialContext.<init>(InitialContext.java:192) ~[?:1.8.0_131]
    [...]

The mentioned directory is where log4j2 places the log files of my web application.

jndi.properties (placed under src/main/resources)

java.naming.factory.initial=org.osjava.sj.SimpleContextFactory
org.osjava.sj.root=conf/

WebListener

    @Override
    public synchronized void contextInitialized(ServletContextEvent event) {
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.osjava.sj.SimpleContextFactory");

        try {
            Configuration config = new Configuration();
            Context ctx = new InitialContext();
            ctx.bind("jdbc/OracleHikariDatasource", config.getDataSource());
        } catch (NamingException | SQLException | RuntimeException ex) {
            log.error(ex.getMessage(), ex);
        }
    }

Is this supposed to work? Am I doing something wrong?

Improvement on Documentation and error handling

This documentation seems outdated:
https://github.com/h-thurow/Simple-JNDI/wiki/DataSource-Configuration-DBCP-2-and-Commons-Pool-2-(New-in-0.15.0)

When following this, I experienced an error in my logfile stating:

ERROR org.osjava.sj.loader.SJDataSourceConverter - Incomplete arguments provided <some more text>

There was no hint as of what exactly was missing. Checking https://github.com/h-thurow/Simple-JNDI/blob/master/src/main/java/org/osjava/sj/loader/convert/SJDataSourceConverter.java#L46 I found out that the properties file should contain these values:

type=javax.sql.DataSource
driver=org.mariadb.jdbc.Driver
url=jdbc:mariadb://localhost/testdb
user=user_name
password=password

So it might be nice to have the documentation updated.
I also noted there are IllegalArgumentExceptions thrown, but these must have been caught/hidden in the Simple-JNDI startup code. Please make them visible so it is more straightforward fixing issues.

Relative path to properties files does not work

Hi,
I think I found a bug, which is serious to my programmer team because it forces us to put our java projects into the same folders on each mache - so we cannot use our personal folders.

On my machine, the working directory (user.dir) is:
C:\Users\stefan\workspace_Projectname\wildfly\application\

org.osjava.sj.root=dataaccess\for_junit\ or:
org.osjava.sj.root=dataaccess/for_junit/ or:

I get the log message: Not found: C:\Users\stefan\workspace_Medion\wildfly\application\dataaccess\for_junit

Which is not true. The folder exists. But when I configure this as an absolute path, then it works. However that properties file in in the resource folder of the project. Therefore it shound not contain may personal name. I really want to use a relative folder.

Enhancement request: system property substitution in resource files

When defining a datasource in a property file, or possibly any other supported resource, it would be great to be able to use system property substitution, e.g.

dataSource.serverName=${database.name}

This could be especially convenient for docker images or for quickly relocating the database server or also for passwords, which could be exported in the environment rather than being written in the file.

Example for Programatic creating datasource with dbcp

This is not an issue just a bit of help.
I have a need where i need to create a JNDI datasource dynamically and your project seemed ideal for me. However I think i got a bit confused and am unable to proceed.

It would be great if you could you give an example of programatically creating a context object for datasource lookup - say for DBCP2.
This should be accessed something like java:comp/env/jdbc/example_JNDI_DS

Thanks a ton in advance,

Disable logging

Simple-JNDI is writing a lot of debug level logs during the test of my application, is there a way to disable logging?

Thank you for your work.

Feature request: ned same result for path with leading separator

For example i have set:
properties.setProperty("bootstrap.initialization.settingsource", "file");
So, if i try to lookup
ctx.ctx.lookup("prbootstrap/");
exception is rised. Seems to not to be bad to make these work the same as
ctx.ctx.lookup("prbootstrap");

Exposed password problem

How is the best way to hide password from datasource.properties file when using simple-jndi? Is there a way to use environment variables?

Programmatical population of JNDI

Since I wanted to create complex objects (DataSource) based on system properties (JDBC-URL, user, password with default values in case they are missing) I decided to populate SimpleJNDI programmatically, using this code:

    DataSource ds = new MyDataSource();

    InitialContext ictx = new InitialContext();
    Context ctx = ictx.createSubcontext("jdbc");
    ctx.bind("ds1", ds);
  
    ctx = ctx.createSubcontext("NonJTA");
    ctx.bind("ds2", ds);

On top of that I added Simple-JNDI to my test classpath and told Maven-Surefire to set the system property like so:

    <dependency>
        <groupId>com.github.h-thurow</groupId>
        <artifactId>simple-jndi</artifactId>
        <version>0.23.0</version>
        <scope>test</scope>
    </dependency>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
                <systemPropertyVariables>
                    <java.naming.factory.initial>org.osjava.sj.SimpleContextFactory</java.naming.factory.initial>
                </systemPropertyVariables>
            </configuration>
        </plugin>

When running the application, I do get a warning message that no root is provided:

    WARN  org.osjava.sj.SimpleJndi - Mistakenly no root provided?

What should be provided, and why?

'#' as a value of a property

If '#' is there as a property value as (in my case it was in a password for Database connection), then it is misunderstood as a start of the comment and getting escaped by the 'CustomProperties parser' of the library.
How to handle this ?

How to setup a transaction manager?

Hello, is it possible to configure a transaction manager to be accessible by JNDI?
I tried this, but didn't work, once each time InitialContext is created, it reads from the properties files and replace all previously binded resources:

            InitialContext jndiCtx = new InitialContext();
            jndiCtx.bind(JNDI_TRANSACTION_MANAGER, createTransactionManager());
            jndiCtx.bind(JNDI_DATASOURCE_NAME, createDataSource());

Do you have any idea no I can have my TransactionManager binded too?

Handling multiple subcontexts

Hi,
due to constraints of my application I need to access resources that are both on a java:app and java:comp subcontext. I can't seem to find, on the other hand, hints on the documentation to bind multiple contexts or to to create an aliased context.

Do you know if it's possible?

Multiple datasources created when using Spring JNDI template

I'm using Simple JNDI with a third party library that uses a Spring JndiTemplate to lookup objects from JNDI. The Spring JndiTemplate runs code like this for any JNDI operation (eg a lookup would execute a JndiCallback that ran ctx.lookup) an object:

    public <T> T execute(JndiCallback<T> contextCallback) throws NamingException {
        Context ctx = getContext();
        try {
            return contextCallback.doInContext(ctx);
        }
        finally {
            releaseContext(ctx);
        }
    }

This is problematic as I have ~5 lookups for what is supposed to be the same connection pool and Spring causes a new Database Connection Pool to be created each time a lookup is run.

Would you approve of adding another property to disable removing contexts on close?

Invalid subcontext 'java:comp' in context ''

Hi,

what is wrong here?

A manual lookup in the unit test works. But when EclipseLink tries to lookup there is this exception...

Apr 27, 2019 12:14:53 AM org.osjava.sj.jndi.MemoryContext lookup
SEVERE: AbstractContext#lookup("java:comp/env/jdbc/MSDataDS"): Invalid subcontext 'java:comp' in context '': 
AbstractContext{namesToObjects={}, 
subContexts={java:comp=AbstractContext{namesToObjects={}, 
subContexts={env=AbstractContext{namesToObjects={}, 
subContexts={jdbc=AbstractContext{namesToObjects={MSDataDS=org.h2.jdbcx.JdbcDataSource::::jdbc:h2:file:./target/msdata;AUTO_SERVER=TRUE::::sa}, 
subContexts={}, 
env={
org.osjava.sj.jndi.shared=true, 
org.osjava.sj.root=src/test/jndi/, 
java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, 
org.osjava.sj.delimiter=/, 
jndi.syntax.separator=/, 
jndi.syntax.direction=left_to_right, 
org.osjava.sj.space=java:comp/env, 
org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@1849db1a, 
nameInNamespace=java:comp/env/jdbc, 
nameLock=true}}, 
env={
org.osjava.sj.jndi.shared=true, 
org.osjava.sj.root=src/test/jndi/, 
java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, 
org.osjava.sj.delimiter=/, 
jndi.syntax.separator=/, 
jndi.syntax.direction=left_to_right, 
org.osjava.sj.space=java:comp/env, 
org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@69c79f09, 
nameInNamespace=java:comp/env, 
nameLock=true}}, 
env={
org.osjava.sj.jndi.shared=true, 
org.osjava.sj.root=src/test/jndi/, 
java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, 
org.osjava.sj.delimiter=/, 
jndi.syntax.separator=/, 
jndi.syntax.direction=left_to_right, 
org.osjava.sj.space=java:comp/env, 
org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory}, nameParser=org.osjava.sj.jndi.SimpleNameParser@1ca25c47, 
nameInNamespace=java:comp, 
nameLock=true}}, 
env={
java.naming.factory.initial=org.osjava.sj.MemoryContextFactory, 
org.osjava.sj.delimiter=/, 
jndi.syntax.direction=left_to_right, 
org.osjava.sj.jndi.ignoreClose=false, 
org.osjava.sj.space=java:comp/env, 
org.osjava.sj.root=src/test/jndi/, 
org.osjava.sj.factory=org.osjava.sj.MemoryContextFactory, 
jndi.syntax.separator=/, 
org.osjava.sj.jndi.shared=true}, 
nameParser=org.osjava.sj.jndi.SimpleNameParser@5fcacc0, 
nameInNamespace=, 
nameLock=false}
[EL Severe]: 2019-04-27 00:14:53.576--ServerSession(1523084197)--Exception [EclipseLink-7060] (Eclipse Persistence Services - 2.7.4.v20190115-ad5b7c6b2a): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [java:comp/env/jdbc/MSDataDS].
Internal Exception: javax.naming.NamingException

Enhancement request: make org.osjava.sj.root not mandatory in jndi.properties

When moving the application, the root folder of Simple-JNDI most of the times needs to be relocated, so I believe it would be good to make it sufficient to specify the value via system properties, while now it's also mandatory to have it in jndi.properties.

Currently, I can specify pretty much all configuration values that would need to be set in jndi.properties via system properties, with the exception of the root path. In fact, I have a jndi.properties file which only contains the root, with a dummy value that I will be later overwriting via system property.

Still, a root declaration in jndi.properties is mandatory because, even if the code already supports that the root is overwritten via system property in SimpleJNDI.overwriteEnvironmentWithSystemProperties(), if the root is not specified in the properties file the code will fail before reaching the above method when the SimpleJndiContextFactory is initialized in line 73, because contextsByRoot is a concurrent hashmap that does not allow a null key and throws a NPE:

          `final String root = (String) environment.get(SimpleJndi.ROOT);`
          `final Context ctx = contextsByRoot.get(root);`
          `if (ctx != null) {`

The code after the map lookup seems to be able to deal with a null Context, so a change like the following should work:

       ` final String root = (String) environment.get(SimpleJndi.ROOT);`
       ` final Context ctx = root != null? contextsByRoot.get(root) : null;`
        `if (ctx != null) {`

If you are OK with the idea I can raise a pull request.

Edit: fix typo and formatting

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.