How to provide preprocessor directives in Java
Asked Answered
G

5

33

CHow can I correctly provide the following functionally from C# in Java?

[C#]

#define PRODUCTION //Change from sandbox to production to switch between both systems.

#if SANDBOX
    using NetSuite.com.netsuite.sandbox.webservices;
#endif

#if PRODUCTION
    using NetSuite.com.netsuite.webservices;
#endif
Gilmer answered 12/12, 2013 at 14:50 Comment(2)
Looks like I can't add an answer since the question's been closed, but I've read about a tool called Prebop (Disclaimer: I've not yet used it), that might do this and it apparently has support for Eclipse. (I agree with others though: in your situation, use DI. -- Just putting this here for other Googlers.)Hinshaw
see this answer, https://mcmap.net/q/102702/-define-in-javaInkblot
I
26

Java doesn't have a preprocessor - so the simple answer is that you can't.

This sort of thing is normally handled in Java using Dependency Injection - which is both more powerful and more flexible.

http://www.vogella.com/articles/DependencyInjection/article.html

Insistency answered 12/12, 2013 at 14:52 Comment(3)
It should be noted that, in the OP's given example, he should also be using DI/IoC in C# anyway -- it's basically a bad example -- I think the question is still valid though, and this answer, while valid for the OP's scenario is kind of disappointing -- (not your fault @TimB, though the answer below about using cpp is kind of interesting...)Hinshaw
I strongly disagree that DI is "more flexible and more powerful." A jpp analogue to cpp similarly would allow for textual substitutions which can aid dramatically in the readability of repeated expressions where you simply don't want a method call, among many things. Not including it in the language started as a silly argument of potential abuse and remains so. Java has many valid arguments regarding abuse (e.g., disallowing MI, not including operator overloading, etc.), but this was one place were I believe they botched it. Thankfully, C# didn't follow in those particular footsteps.Chalfant
I came from C, I used to use the pre-processor all the time. I've not found anything in decades of using Java where I've needed the pre-processor. There's always a cleaner way. Particularly with things like Cucumber available for when you need a less code-focussed approachInsistency
G
10

Java doesn't have a preprocessor, yet that doesn't mean that you can't run Java code through cpp - though it would not be supported by any tools, AFAIK.

Ganef answered 12/12, 2013 at 15:6 Comment(1)
Looks like I can't add an answer since the question's been closed, but I've read about a tool called Prebop (Disclaimer: I've not yet used it), that might do this and it apparently has support for Eclipse. (I agree with others though: in the OP's situation, he should use DI. -- Just putting this here for other Googlers.)Hinshaw
S
1

Use Dependency Injection/Inversion of Control. Depending on your actual needs, you might be able to get away with something as simple as property file/environment variables to control things.

You might be able to use static defines around some types of initialization/code.

Savour answered 12/12, 2013 at 14:53 Comment(3)
Using the example in the post, how would DI/IoC help? From what I've read (albeit briefly) it appears that DI is mostly used for decoupling and not conditional compilation. My specific use case surrounds changing import statements en mass in order to connect to a sandbox vs production system. Is there a specific tutorial/set of docs I should read?Gilmer
DI/IoC is "conditional compilation" at run time. Without knowing what you're actually trying to swap in and out, I'm guessing, but you'd use one of two webservice implementations, e.g., in development, they'd all be stubbed out to return known values. This is often done for testing purposes, for example. It's more likely we'd use different connection parameters/endpoints in development, which is generally just config values, which wouldn't require DI.Savour
A solution would be to use the same namespace for both versions, putting each version in its own JAR archive and just loading the appropriate one.Cleanse
D
1

You can use something based on <#FreeMarker>.

enter image description here

source: https://github.com/mkowsiak/jpp

However, this solution will require pre-compilation step, if you want to change the code. On the other hand, you can still create code that works without pre-processing steps - sort of "default" compilation.

Ditto answered 28/8, 2019 at 12:35 Comment(0)
B
0

I'm using java-comment-preprocessor. It is very easy and convenient and provides also integration for Maven, Ant and Gradle. It is using Java comments and a preprocessor is used generating the actual code based on the preprocessor flags, e.g.:

//#if simulator
private final static int FOO = 2;
//#else
private final static int FOO = 1;
//#endif

Maven integration:

<plugin>
                <groupId>com.igormaznitsa</groupId>
                <artifactId>jcp</artifactId>
                <version>7.0.5</version>
                <executions>
                    <execution>
                        <id>preprocessSources</id>
                        <phase>process-sources</phase>
                        <goals>
                            <goal>preprocess</goal>
                        </goals>
                        <configuration>
                            <vars>
                                <simulator>${simulator}</simulator>
                            </vars>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
Bioecology answered 8/6, 2023 at 23:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.