A non-opinionated User-Agent analysis proxy written in Java 8.
The purpose of this project is to encapsulate several popular useragent analysis frameworks for the JVM (and other languages) under a single facade/interface, allowing developers to easily move between frameworks/implementations in any case some becomes obsolete/updated or simply doesn't quite fit the accuracy needs of the task at hand
- Provides both synchronous & fully asynchronous APIs.
- Pluggable architecture for both caching & processing(parsing) modules.
Simply add the 'useragent-analyzer-dist' dependency.
Note that this distribution jar relies on the user providing the j2v8 jar for the targeted architecture. The following examples targets 64 bit linux execution environments, but other operating systems are supported as well. See Maven Central for additional information.
<dependencies>
...
<dependency>
<groupId>org.sheinbergon</groupId>
<artifactId>useragent-analyzer-dist</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.eclipsesource.j2v8</groupId>
<artifactId>j2v8_linux_x86_64</artifactId>
<version>4.8.0</version>
</dependency>
...
</dependencies>
compile group: 'com.eclipsesource.j2v8', name: 'j2v8_linux_x86_64', version: '4.8.0'
compile group: 'org.sheinbergon', name: 'useragent-analyzer-dist', version: '0.0.1'
UserAgentAnalyzer analyzer = UserAgentAnalyzer.builder()
.processor(UaParserJsProcessor.builder().build())
.build();
UserAgentIngredients ingredients = analyzer.analyze("Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1")
ingredients.getOsName() // iOS
ingredients.getDeviceType() // MOBILE
AsyncUserAgentAnalyzer analyzer = AsyncUserAgentAnalyzer.builder()
.processor(UaParserJsAsyncProcessor.builder().build())
.build();
analyzer.analyze("Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1")
.thenApply(UserAgentIngredients::getDeviceModel)
...
analyzer.teardown();
See Implementation Specs below
- Uses the popular javascript useragent parsing library ua-parser.js
- Javascript code is executed using J2V8
- Requires an explicit J2V8 dependency defintion per operating system/architecture. See supported architectures here
- As V8Engine instances are not thread-safe, an object-pool is used to acheive thread-safety with concurrency, supporting confiugrable pool size & allocation timeout
- Async version also supports executor pools size for V8 Engine allocation and ingestion
// Sync
UserAgentAnalyzer.builder()
.processor(UaParserJsProcessor.builder()
.v8AllocationTimeout(1000L)
.v8PoolSize(5)
.build())
...
// Async
AsyncUserAgentAnalyzer.builder()
.processor(UaParserJsAsyncProcessor.builder()
.ingestionConcurrency(4)
.v8AllocationConcurrency(16)
.v8AllocationTimeout(1000L)
.v8PoolSize(5)
.build())
...
- Default cache implementation, never caches anything (always misses)
- Caching module implemented on top of caffeine
- Supports max entries configuration
// Sync
UserAgentAnalyzer.builder()
.cache(CaffeineCache.builder()
.maxEntries(100000)
.build())
...
// Async
AsyncUserAgentAnalyzer.builder()
.cache(CaffeineAsyncCache.builder()
.maxEntries(100000)
.build())
...